这是一个最小的例子:
#include <iostream>
struct B {
B() { x = 42; }
static int x;
};
int B::x;
template <int N>
struct A {
int foo() { return b.x; }
static B b;
};
template<int N>
B A<N>::b;
//template struct A<2>; // explicit instantiation with N = 2 (!)
int main(int argc, char **argv) {
std::cout << A<1>().foo() << std::endl;
return 0;
}
该程序使用 g++ 4.9.2 写入 42,但使用 Visual Studio 2015 RC 写入 0。另外,如果我取消显式实例化的注释,VS2015RC 也会给出 42,这很有趣,因为这里的模板参数与main
函数中使用的不同。
这是一个错误吗?我假设 g++ 是正确的,因为有对b
inside的引用foo
,所以B
应该调用构造函数。
编辑:有一个简单的解决方法 - 如果在 中有一个非静态变量B
,在 中引用A
,VS2015RC 将正确编译:
// ...
struct B {
B() { x = 42; }
static int x;
int y; // <- non-static variable
};
// ...
template <int N>
struct A {
int foo() { b.y; return b.x; } // <- reference to b.y
static B b;
};
这似乎有效,尽管b.y
作为一个声明,显然是 NOP。