Visual Studio的隐式静态成员初始化失败

时间:2016-08-01 16:11:36

标签: c++ visual-c++ initialization c++14 static-members

采取以下代码段

#include <iostream>
using namespace std;

template<int i, typename T = int> struct A
{
    T num = i;
    A<i, T>()
    {
        cout << "Instantiated a A<" << i << ">" << endl;
    }
};

template<int i, int i2> struct B
{
    static A<i> a;
    static A<i * i2> a2;
};
template<int i, int i2> A<i> B<i, i2>::a{};
template<int i, int i2> A<i * i2> B<i, i2>::a2{};

template<typename T> struct C
{
    static void doSomething()
    {
        cout << "Have a A<" << T::a.num << "> and a A<" << T::a2.num << "> in C" << endl;
    }
};

int main() {
    typedef C<B<2, 2>> c;
    cout << "Typedefined a C\nCalling static member function to initialize C<B<2, 2>>'s B<2, 2>'s A<>s" << endl;
    c::doSomething();
    return 0;
}

现在使用gcc,然后编译(包括C ++ 11和C ++ 14)和instantiates a and a2 as expected

感谢WhozCraig,这也与clang编译。

但是使用Visual C ++(2015版),我得到一个解析错误。

main.cpp(37) error C2143: syntax error: missing ';' before '<end Parse>'

后面跟着一些笔记

main.cpp(19): note: while compiling class template static data member 'A<2,int> B<2,2>::a'
main.cpp(26): note: see reference to class template instantiation 'B<2,2>' being compiled
main.cpp(25): note: while compiling class template member function 'void C<B<2,2>>::doSomething(void)'
main.cpp(33): note: see reference to function template instantiation 'void C<B<2,2>>::doSomething(void)' being compiled

main.cpp(33): note: see reference to class template instantiation 'C<B<2,2>>' being compiled

这里发生了什么?

1 个答案:

答案 0 :(得分:3)

我能够减少测试用例,找出问题(这似乎是Visual C ++编译器中的一个错误)并找到解决方法:

#include <iostream>
using namespace std;

template<int i> struct A
{
    int num = i;
    A() {}
};

template<int i> struct B
{
    static A<i> a;
};

// MSVC doesn't like this syntax
//                         |||
//                         vvv
template<int i> A<i> B<i>::a{};

// To fix the error, rewrite the above line in one of the below ways:
//
// template<int i> A<i> B<i>::a;
// template<int i> A<i> B<i>::a = {};

int main() {
    typedef B<2> B2;
    cout << B2::a.num << endl;
    return 0;
}