How to setup a global container (C++03)?
我想定义一个全局容器(C++ 03),这是我尝试过的一个示例代码,不起作用。
1 2 3 4 5 6 7 8 | #include <vector> #include <string> using namespace std; vector<string> Aries; Aries.push_back("Taurus"); // line 6 int main() {} |
编译错误:
1 | prog.cpp:6:1: error: 'Aries' does not name a type |
似乎我可以定义一个空的全局向量,但不能填充它。看起来像在C++ 03中,我也不能指定一个初始化器,例如:
1 | vector<string> Aries = {"Taurus" }; |
我在这里犯了错误,或者我该如何解决这个问题?
我尝试在StAdvExcel上搜索,看看这是否已经被回答过,但是只遇到了这些问题:C++中的全局对象,在C++中定义全局常量,这并没有帮助回答这个问题。
虽然函数外部的声明和初始化(如
1 2 3 4 5 6 7 8 | std::vector<string> Aries; /* ... */ int main() { Aries.push_back("Taurus"); /* ... */ } |
其他方式(不填充主向量)单值
还有其他方法不需要
1 2 3 4 5 | std::vector<string> Aries(1,"Taurus"); /* ... */ int main() { /* ... */ } |
如果多次需要相同的值,可以简单地调整
现在这变得有点棘手了。您希望使用合适的构造函数来填充
我们可以忘记
1 2 3 4 5 6 7 8 9 10 11 12 | std::string const values[] = {"Taurus","Ares","Testos"}; template <class T, size_t N> T* begin(T (&array)[N]){ // this is already in C++11, very helpful return array; } template <class T, size_t N> T* end(T (&array)[N]){ return array+N; } std::vector<std::string> Aries(begin(values), end(values)); |
注意,
然而,这个解决方案引入了一个新的全局变量,这并不是很好。让我们后退一步。我们需要
1 2 3 4 5 6 7 8 | namespace { std::vector<std::string> initializer(){ const std::string dummy_array[] = {"Taurus","Ares","Testos"}; return std::vector<std::string>(begin(dummy_array), end(dummy_array)); } } std::vector<std::string> Aries(initializer()); |
此示例同时使用复制构造函数和范围构造函数。您还可以创建一个临时向量,并使用
我找到了一个整洁的解决方案来"初始化"C++ 03全局STL容器(并且实际上是在EDCOX1(23)之前)全局执行代码。这将使用逗号运算符。见例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #include <vector> #include <string> #include <iostream> using namespace std; vector<string> Aries; // dummy variable initialization to setup the vector. // using comma operator here to cause code execution in global scope. int dummy = (Aries.push_back("Taurus"), Aries.push_back("Leo"), 0); int main() { cout << Aries.at(0) << endl; cout << Aries.at(1) << endl; } |
产量
1 2 | Taurus Leo |
唯一真正的问题是额外的全局变量。
我的经验是,这种"惊人但又可怕"(帽子提示)的解决方案是不可预测的。您的初始化在加载时运行。你方不能保证装船。因此,使用该容器的所有内容都必须在同一个模块中,或者以某种方式保证在访问该容器之前加载该模块。否则,容器构造函数还没有运行,但是您的代码很乐意调用它的访问器。
当它出错时,它就会出错,而且错误是编译器、平台和与月球相关的阶段——在所有情况下,都不会给出最遥远的线索来说明什么是向南的。
为了完整性,这个解决方案使用迭代器对构造函数和普通的旧数组初始值设定项。
1 2 3 4 5 6 7 8 9 10 11 12 | #include <vector> #include <string> #include <iostream> using namespace std; string contents[] = {"Taurus","Leo"}; vector<string> Aries(contents, contents + sizeof contents/sizeof contents[0]); int main() { cout << Aries.at(0) << endl; cout << Aries.at(1) << endl; } |
这可能更清楚,但它调用了更多的复制构造函数。