2016-08-01 69 views
0

採取下面的代碼片斷失敗隱式靜態成員初始化由Visual Studio

#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,這也與鏗鏘編譯。

但是,使用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 

這到底是怎麼回事緊隨其後?

+0

FWIW,此編譯與鐺3.8,STD = C++ 14也沒有問題。不過,我擔心'main.cpp'第37行可能會報告一個錯誤,當您爲複製發佈的整個代碼只有34行通過'main()'中的關閉'}時。 – WhozCraig

+0

@WhozCraig Visual實現有兩行(include和'_getch()')。奇怪的是,它報告文件結尾後出現錯誤... –

+2

'A ()'這個語法在做什麼? –

回答

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; 
} 
+0

哦微軟...謝謝 –

+1

你有沒有向微軟報告錯誤?如果是這樣,你可以在這裏發佈一個錯誤報告的鏈接嗎? – ildjarn

+0

@ildjarn不,我沒有。 – Leon