views:

37

answers:

2

VERSION 1

class Doh {
private:
    static std::map<const std::string, const Doh*> someMap;
    std::string stringValue_;
public:
    Doh(std::string str) : stringValue_(str) {
        Doh::someMap.insert(
            std::make_pair<const std::string,const Doh*>
                (this->stringValue_,this)
        );
    }
}

The above was ok with MSVC 2010 but with MSVC 2008 it fails – and I guess it is because the object is not constructed yet when it is inserted in the map (I got a memory access violation).

So, I tried a delayed insertion, which worked:

VERSION 2

Doh(std::string str) : stringValue_(str) {
    boost::thread(&Doh::insertIntoTheStaticMap,this);
}
void insertIntoTheStaticMap() {
    boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
    Doh::someMap.insert(
        std::make_pair<const std::string,const Doh*>
            (this->stringValue_,this)
    );
}
But as you might be able to guess, my intention is to have the static Doh::someMap as a common lookup dictionary.

VERSION 1 didn’t need any thread-safety because I would create all Doh instances in the same thread – in initialization blocks - which would be called by dynamic initializers before I enter main().

But with VERSION 2, the naïve sleep() is neither graceful nor reliable (not to mention, I might need to lock the map before insertion).

What would be a nice KISS approach?

A: 

In neither version is there any sign of init for stringvalue_ - what does the debugger show you about this key when you hit the map insert in version 1 of the code? How is this field set up, and what is its type?

Running this in the debugger for VS2008 should allow you to narrow down the point of failure into the <map> source, I would have thought.

Steve Townsend
+1  A: 

Only potential issue I see is the initialization of the static member, if there are multiple source files. Try guarding it with a function.

class Doh {
private:
    static std::map< std::string, Doh * > &get_map() {
        static std::map< std::string, Doh * > someMap;
        return someMap; // initialize upon first use
    }
    std::string stringValue_;
public:
    Doh(std::string str) : stringValue_(str) {
        get_map().insert(
            std::make_pair
                (this->stringValue_,this)
        );
    }
};
Potatoswatter
That worked - I thought static initializers would always preceed dynamic initializers.
Ustaman Sangat