2013-02-23 115 views
11

我不確定它是Clang 3.2中的錯誤還是違反了C++ 03,但似乎模板類的模板化構造函數的顯式實例化失敗,但顯式實例化了模板化模板類的成員函數成功。模板類的模板化構造函數的顯式實例化

例如,下面的編譯沒有一個問題都鐺++和g ++:

template<typename T> 
class Foo 
{ 
public: 
    template<typename S> 
    void Bar(const Foo<S>& foo) 
    { } 
}; 
template class Foo<int>; 
template class Foo<float>; 

template void Foo<int>::Bar(const Foo<int>& foo); 
template void Foo<int>::Bar(const Foo<float>& foo); 
template void Foo<float>::Bar(const Foo<int>& foo); 
template void Foo<float>::Bar(const Foo<float>& foo); 

而沒有與G ++警告以下編譯但失敗鐺++:

template<typename T> 
class Foo 
{ 
public: 
    template<typename S> 
    Foo(const Foo<S>& foo) 
    { } 
}; 
template class Foo<int>; 
template class Foo<float>; 

template Foo<int>::Foo(const Foo<int>& foo); 
template Foo<int>::Foo(const Foo<float>& foo); 
template Foo<float>::Foo(const Foo<int>& foo); 
template Foo<float>::Foo(const Foo<float>& foo); 

特別地,我看到兩種形式的錯誤消息:

TemplateMember.cpp:12:20: error: explicit instantiation refers to member 
     function 'Foo<int>::Foo' that is not an instantiation 
template Foo<int>::Foo(const Foo<int>& foo); 
       ^
TemplateMember.cpp:9:16: note: explicit instantiation refers here 
template class Foo<int>; 
      ^

這是違規行爲的標準或鏗鏘++錯誤?

+3

看起來像有效的C++ 03。可能在Clang中出現bug ++ – 2013-02-23 21:34:30

回答

5

看起來您已經找到了GCC錯誤。這些都命名隱式聲明的拷貝構造函數:

template Foo<int>::Foo(const Foo<int>& foo); 
template Foo<float>::Foo(const Foo<float>& foo); 

每[temp.explicit] P4,

如果顯式實例名稱的聲明隱式聲明的特殊成員函數(第12條) ,該計劃是不合格的。

因此,Clang拒絕此代碼是正確的。

+0

謝謝Richard!你絕對正確。通過顯式聲明構造函數Foo(const Foo &foo)並刪除拷貝構造函數的顯式實例,程序然後用Clang編譯。 – 2013-02-25 22:00:16