2009-10-26 44 views
1

我使用下面的代码获得以下错误。在全局级别实例化(C++)

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; 
} 
+2

你的问题不是“在全球范围内实例化”,而是“试图在全球范围内执行一个语句”。你不能这么做,对不起。 – 2009-10-26 23:17:02

回答

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

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

+2

为什么downvotes?至少留下建设性的意见。 – 2009-10-26 23:40:29

+0

我没有让你失望,但我想我明白你为什么不是一个好的答案。它没有解决这个问题。静态初始化和有序的危险可能是他的问题的答案的一部分,但你没有包括这一点。 – 2009-10-27 00:56:16

+0

在C++中没有这样的静态初始化器。全局变量由构造函数初始化。此外链接的文章是可怕的,充满了非常糟糕的建议。 – 2009-10-27 06:43:57

4

简而言之,正如你所见,是:你不能那样做。

我想你真正想要的是这样的:

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

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

如果你真的需要初始化执行main()之前,你会经常看到的例子是这样的:

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

不过,现在您有一个新问题,即无法保证在_helper_obj之前创建了map。解决这个问题的一个方法是将它们合并:

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); 

我无法找到这是否是安全的静态对象的信息,虽然。