作为一个例子,考虑这个标题:
#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.的单一定义一样
实际的需求有点像语言律师(实例化时的依赖名称必须相同,等等),但我认为这一点让你明白了:-)