繁体   English   中英

C ++全局变量的初始化顺序

[英]c++ initialization order of globals

这是便携式的还是至少可以安全地与g ++一起使用?

#include <iostream>
#include <vector>

struct c {};
std::vector<c*> v;
struct i : c { i () { v.push_back (this); } } a, b, c;

int main () {
  std::cout << v.size () << "\n"; // outputs 3 with g++
}

编辑:

好的,我需要做的有点困难:与模板相同的代码:

#include <iostream>
#include <vector>

template < typename T > struct c {};
template < typename T > struct cv { static std::vector<c<T>*> v; };
template < typename T > std::vector<c<T>*> cv<T>::v;
template < typename T > struct i : c<T> { i () { cv<T>::v.push_back (this); } };

cv<int> dummy; // even this won't initialize cv<int>::v
i<int> a, b, d;

int main () {
  std::cout << cv<int>::v.size () << "\n"; // outputs 0 :-(
}

我该如何解决上述问题?

编辑2:

这是宏的一个丑陋修补程序(我希望有更好的方法可以做到这一点):

#include <iostream>
#include <vector>

template < typename T > struct c {};
template < typename T > struct cv;
#define INITCV(X) \
  struct v##X { static std::vector<c<X>*> v; }; \
  std::vector<c<X>*> v##X::v; \
  template <> struct cv<X> { typedef v##X V; }
template < typename T > struct i : c<T> { i () { cv<T>::V::v.push_back (this); } };

INITCV(int);
i<int> a, b, d;

int main () {
  std::cout << cv<int>::V::v.size () << "\n"; // outputs 3 again :-)
}

(顺便说一句,我应该发布新的问题而不是进行编辑吗?)

转换单元中的全局变量(通常对应于.c文件)是按顺序初始化的,因此这是安全的。 唯一的问题是,全局对象位于相互依赖的不同目标文件中。

这是在§3.6.2/ 2的标准中指定的:

在单个转换单元中定义了有序初始化的变量,应按其在转换单元中定义的顺序进行初始化。

全局变量只要不声明为static ,就可以对初始化进行排序。

订单保证是。

安全:有问题。 安全取决于您的意思。
但是按照书面形式,它是可移植的,并且不会在我知道的任何编译器上崩溃。

对于您的更新问题,我没有涉足标准以找出何时应该初始化隐式实例化模板的成员,但是显式实例化似乎是解决方案:

template class cv<int>; // Not a dummy. Declares the template like a class.

14.7.2 / 7为Standardese:

类模板特化的显式实例化包含先前未在包含显式实例化的翻译单元中显式专门化的所有成员的实例化。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM