can I use STL on visual C++ type?

L

learning

I'm trying to make a map to store the static information of pairs of
string and hkey. So here is the code I ahve so far which DOES NOT
compile. Since I am very new to STL, I do not know how to fix it.

typedef std::map<LPCWSTR,HKEY> MapType;
typedef MapType::value_type ValuePair;
MapType keyMap

keyMap.insert(ValuePair("HKCR",HKEY_CLASSES_ROOT));
keyMap.insert(ValuePair("HKLM",HKEY_LOCAL_MACHINE));
keyMap.insert(ValuePair("HKCR",HKEY_CURRENT_USER));
keyMap.insert(ValuePair("HKU",HKEY_USERS));
keyMap.insert(ValuePair("HKDD",HKEY_DYN_DATA));

so that later on I can use it as this:
WalkRegistry("HKLM","Software\\ActiveState");
The WalkRegistry has body of follows:
HRESULT WalkRegistry(LPCWSTR rootKey,LPCWSTR subKey){
HRESULT ret=S_FAIL;
HKEY hSubkey=NULL;
if(ERROR_SUCCESS==::RegOpenKeyEx(rootKey,subKeyNULL,KEY_READ,&hSubkey))
{
::RegCloseKey(hSubkey);
} else {
std::cout<<"error"<<std::endl;
};

return ret;
}

Can I use STL this way?
Thanks
 
P

Phlip

Yes you can use it, but you need to follow STL rules as well as Win32 SDK
rules.
I'm trying to make a map to store the static information of pairs of
string and hkey. So here is the code I ahve so far which DOES NOT
compile. Since I am very new to STL, I do not know how to fix it.

typedef std::map<LPCWSTR,HKEY> MapType;

Stop right there. LPCWSTR is a wide string. Do you really want a
std::wstring there?

Or do you need a std::string there, and is the W a typo?

Next, map needs to be able to compare its keys. LPCWSTR is like char *,
where > simply compares the memory address of two pointers (IIRC).

You need a lexical comparison, so two "HKCR" keys get interpreted as the
same key (not two different memory locations). So you need no pointers, you
need real string objects:

std::string;
std::wstring;
CString;
CStringW;

Next, the exact behavior of CString and its ... ilk ... is off-topic for
this newsgroup. An MS-specific group will be better qualified to tell if I
got any of these details wrong.

Next...
keyMap.insert(ValuePair("HKCR",HKEY_CLASSES_ROOT));

One typically populates a map by assignment:

keyMap[L"HKCR"] = HKEY_CLASSES_ROOT.

Next, your computer already "knows" that HKCR is an alias for
HKEY_CLASSES_ROOT. Why are you telling it redundant information? (Answer on
an on-topic newsgroup! ;-)
WalkRegistry("HKLM","Software\\ActiveState");

Have you softened this topic with a search on groups like codeproject.com?
There are lots of cute Registry wrappers out there...
 
V

Victor Bazarov

learning said:
I'm trying to make a map to store the static information of pairs of
string and hkey. So here is the code I ahve so far which DOES NOT
compile.

Does not compile and says WHAT?
Since I am very new to STL, I do not know how to fix it.

What you posted has plenty of non-standard things that are off-topic
here. If you want us to be able to help you, post the error messages.
Another possibility for you is to post in 'microsoft.public.vc.language'
or 'microsoft.public.vc.mfc', where all those MS-specific types and
constructs are on topic.
typedef std::map<LPCWSTR,HKEY> MapType;
typedef MapType::value_type ValuePair;
MapType keyMap

keyMap.insert(ValuePair("HKCR",HKEY_CLASSES_ROOT));
keyMap.insert(ValuePair("HKLM",HKEY_LOCAL_MACHINE));
keyMap.insert(ValuePair("HKCR",HKEY_CURRENT_USER));
keyMap.insert(ValuePair("HKU",HKEY_USERS));
keyMap.insert(ValuePair("HKDD",HKEY_DYN_DATA));

so that later on I can use it as this:
WalkRegistry("HKLM","Software\\ActiveState");

I don't see any 'keyMap' used here. Why do you need it?
The WalkRegistry has body of follows:
HRESULT WalkRegistry(LPCWSTR rootKey,LPCWSTR subKey){
HRESULT ret=S_FAIL;
HKEY hSubkey=NULL;
if(ERROR_SUCCESS==::RegOpenKeyEx(rootKey,subKeyNULL,KEY_READ,&hSubkey))
{
} else {
std::cout<<"error"<<std::endl;
};

return ret;
}

Can I use STL this way?

Which way? I only see a bunch of 'insert' calls. Did you mean to
look your values up somehow?

V
 
S

Stuart Golodetz

Phlip said:
Yes you can use it, but you need to follow STL rules as well as Win32 SDK
rules.
Next...

keyMap.insert(ValuePair("HKCR",HKEY_CLASSES_ROOT));

One typically populates a map by assignment:

keyMap[L"HKCR"] = HKEY_CLASSES_ROOT.

The assignment method certainly looks nicer, but using insert seems to be
more efficient (if that matters in a given situation). Here's the code I
used to time it (unfortunately I had to use a non-Standard library to time
it in milliseconds, but it's fairly obvious what's going on):

#include <SDL.h>
#include <iostream>
#include <map>
#include <utility>

std::map<int,int> theMap;

unsigned int time_it(void (*f)())
{
unsigned int start = SDL_GetTicks();
f();
return SDL_GetTicks() - start;
}

void map_array()
{
for(int i=0; i<100000; ++i) theMap = i;
}

void map_insert()
{
for(int i=0; i<100000; ++i) theMap.insert(std::make_pair(i,i));
}

int main(int argc, char *argv[])
{
SDL_Init(SDL_INIT_TIMER);
for(int i=1; i<=10; ++i)
{
std::cout << "TEST #" << i << '\n';
std::cout << "Associative array version: " << time_it(&map_array) <<
" milliseconds\n";
theMap.clear();
std::cout << "Insert version: " << time_it(&map_insert) << "
milliseconds\n\n";
theMap.clear();
}
SDL_Quit();
return 0;
}

The results I got were (condensed to save space):

TEST #1 Associative array version: 2549 milliseconds Insert version: 1977
milliseconds
TEST #2 Associative array version: 2434 milliseconds Insert version: 1959
milliseconds
TEST #3 Associative array version: 2429 milliseconds Insert version: 1959
milliseconds
TEST #4 Associative array version: 2424 milliseconds Insert version: 1953
milliseconds
TEST #5 Associative array version: 2481 milliseconds Insert version: 2070
milliseconds
TEST #6 Associative array version: 2502 milliseconds Insert version: 2039
milliseconds
TEST #7 Associative array version: 2496 milliseconds Insert version: 2137
milliseconds
TEST #8 Associative array version: 2569 milliseconds Insert version: 2083
milliseconds
TEST #9 Associative array version: 2585 milliseconds Insert version: 2013
milliseconds
TEST #10 Associative array version: 2545 milliseconds Insert version: 1994
milliseconds

This doesn't indicate that using insert is always the right way to go, but
it does seem to suggest that if you're adding a large number of key-value
pairs to a map, you might want to prefer insert. Assuming I haven't done
something stupid in my code, it would seem to be about 20% faster (the
associative array version takes roughly 2.5s each time, the insert version
takes about 2s, 2/2.5 roughly equals 0.8...). FWIW, I haven't tried it with
other data types, so for all I know this might just be the case when the key
type is int. YMMV :)

HTH,
Stu
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,161
Latest member
GertrudeMa
Top