2016-04-07 19 views
8

でこのコードは打ち鳴らす3.7.1(なし診断付き)でコンパイルしますが、GCC5.3.0live example)で失敗しない:テンプレート友情エラーのコンパイルが、打ち鳴らす

#include <iostream> 

template<typename T> 
struct A { 
    void foo() 
    { 
     static_cast<T*>(this)->implementation(); 
    } 
}; 

struct Crtp : A<Crtp> { 
    template<typename T> 
    friend struct A; 
private: 
    void implementation() { std::cout << "implementation()\n"; } 
}; 

int main() 
{ 
    Crtp c; 
    c.foo(); 
} 

GCCのエラーメッセージは以下の通りです:

右である1

main.cpp:13:16: error: specialization of 'A' after instantiation friend struct A;

、なぜ?それはGCC/clangのバグですか?

答えて

4

古いg ++バグ(https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52625)と思われます。

私が正しく理解していれば、

+1

あなたが正しいです。さらに、gccには多くの[友人の問題](https://gcc.gnu.org/bugzilla/showdependencytree.cgi?id=65608&hide_resolved=1)があるようです。 – akakatak

3

これはgccのバグだと思います。

テンプレートフレンドクラスの宣言は、宣言であり定義ではありません。 クラステンプレートの再宣言は、クラスキー(N4527 14.5.1.4を参照)と異なる場合を除き、許可されます。

特殊化またはインスタンス化は、2回以上発生することがあります。 明示的な特殊化は1回だけ実行できます(N4527 14.7.3.6)。

次に、明示的な特殊化がないため、gccの診断は奇妙です。

0

我々はいくつかのテンプレートの名前解決のオッズを持っている、報告、決して修正:

struct Crtp : A<Crtp> { 
    A x; // A refers to A<Crtp> 
}; 

は今のものがはっきりしている:

template<typename T> friend struct A; 

はを参照

template<typename T> friend struct A<Crtp>; 

これは...はい、部分的な特殊化(本当にトリッキーなもの)です。

ここでGCCは正しいです。

あなたが本当に何が必要なのかは、次のとおりです。

struct Crtp : A<Crtp> { 
friend struct A; 
private: 
    void implementation() { std::cout << "implementation()\n"; } 
}; 
関連する問題