在全球范围内实例化(C ++)

时间:2009-10-26 23:13:07

标签: c++ global-variables instantiation

我使用下面的代码收到以下错误。

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

-

#include <string>
#include <map>

class Foo {

};

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

int main()
{

    return 0;
}

3 个答案:

答案 0 :(得分:13)

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

直到C ++ 0x成为主流,我建议使用boost。填充map会变成一块蛋糕。这是一个例子:

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

答案 1 :(得分:4)

如你所见,简短的答案是:你做不到。

我认为你真正想要的是:

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

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

如果确实需要在main()之前执行初始化,您会经常看到如下示例:

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

但是,现在您遇到了一个新问题,即无法保证在map之前创建_helper_obj。解决这个问题的一种方法是将它们结合起来:

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

但是,通常不建议继承STL容器类。请注意,此示例隐藏任何其他构造函数,并且STL基类没有虚拟析构函数。这被许多人认为是“黑客”,应该真的避免。

另一种方法是使用std::map

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

map_holder.map.find(...

但当然这会使地图的任何使用变得复杂。

更新

我忘了提及另一个选项,使用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);

但是我无法找到关于静态对象是否安全的信息。

答案 2 :(得分:1)

看起来你想要的是一个静态初始化器。我建议你阅读this。它说明了静态初始化器的使用以及它们的主要缺陷,静态初始化顺序。