开发者

Instantiating at global level (C++)

开发者 https://www.devze.com 2022-12-09 17:52 出处:网络
I get the following error with the code below. expected constructor, destructor, or type conversion before \'=\' token

I get the following error with the code below.

expected constructor, destructor, or type conversion before '=' token

--

#include <开发者_C百科string>
#include <map>

class Foo {

};

std::map<std::string, Foo> map;
map["bar"] = Foo();

int main()
{

    return 0;
}


map["bar"] = Foo(); // This line is a statement not a declaration.
                    // You have to put it in main, or any execution context

Untill C++0x becomes mainstream, I would suggest using boost. Filling the map becomes piece of cake. Here is an example:

std::map<std::string, Foo> mymap;
...
int main()
{
  insert(mymap)
   ("First",  Foo(...))
   ("Second", Foo(...))
   ("Third",  Foo(...));
   ...
}


Short answer, as you've seen, is: you can't do that.

I think what you really want is this:

std::map<std::string, Foo> map;

int main()
{
    map["bar"] = Foo();

If you really need the initialization to execute before main() you will often see examples like this:

namespace {
   struct StaticInitHelper {
       StaticInitHelper() { map["bar"] = Foo(); }
   } _helper_obj;
}

However, now you have a new problem which is that there's no guarantee that map is created before _helper_obj. One way around this is to combine them:

namespace {
   struct StaticInitHelper : public std::map<std::string, Foo> {
       StaticInitHelper() { (*this)["bar"] = Foo(); }
   } map;
}

Inheriting from STL container classes is generally not recommended, however. Note that this example hides any other constructors and the STL base class does not have a virtual destructor. This would be considered a "hack" by many, and should really be avoided.

Yet another alternative is to define the class with a std::map:

namespace {
   struct StaticInitHelper {
       StaticInitHelper() { map["bar"] = Foo(); }
       std::map<std::string, Foo> map;
   } map_holder;
}

map_holder.map.find(...

But of course this complicates any use of the map.

Update:

I forgot to mention another option, using boost::assign:

#include <boost/assign/list_of.hpp>

map<int,int> map = boost::assign::map_list_of(1,2)(2,3)(3,4)(4,5)(5,6);

I can't find information on whether that's safe on a static object, though.


It looks like what you want is a static initializer. I suggest you read this. Its illustrative of the use of static initializers and also of their primary pitfall, static initialization order.

0

精彩评论

暂无评论...
验证码 换一张
取 消