例如,考虑以下标头:
#include <iostream>
template<bool = true>
struct A {
A() {
static int x;
std::cout << &x << "\n";
}
};
static A<> a;
如果我有两个不同的 C++ 文件,包括这个文件——它会打印两次相同的地址吗,保证?更重要的是,如果x
是具有非平凡构造函数的不同类型的对象,是否可以保证只运行一次?
例如,考虑以下标头:
#include <iostream>
template<bool = true>
struct A {
A() {
static int x;
std::cout << &x << "\n";
}
};
static A<> a;
如果我有两个不同的 C++ 文件,包括这个文件——它会打印两次相同的地址吗,保证?更重要的是,如果x
是具有非平凡构造函数的不同类型的对象,是否可以保证只运行一次?
标准 [C++11 14.8/2] 说
从模板实例化的每个函数模板特化都有它自己的任何静态变量的副本。
我假设(并且真诚地希望)模板类的成员函数以相同的方式处理,尽管我找不到这样说的特定语言。
在任何情况下,除了与在多线程上下文中初始化静态变量相关的常见风险外,我相信这会很好。A<true>::A()
(和内部的“ static int A<true>::A::x
”)将被标记为弱符号,并且将在链接时选择一个版本,与任何其他模板相同。(显然, 的实例化A<false>
将不同于A<true>
。)
编辑评论:
[3.2/5] 节似乎涵盖了对不同翻译单元的担忧,定义了 ODR:
如果 D 是一个模板并且在多个翻译单元中被定义,那么……[如果定义相同]……程序的行为就好像有一个 D 的定义一样。
实际要求更多的是语言法律(实例化时的依赖名称必须相同,等等),但我认为这是让你明白的一点:-)