3

このトピックに関する多くの回答を注意深く読みましたが、ネストされたテンプレート クラスのメンバーである非テンプレート関数のスコープで、これら 2 つのキーワードが必要な場合と必要でない場合を正確に把握できません。

私のリファレンス コンパイラは GNU g++ 4.9.2 と clang 3.5.0 です。

次のコードでは、何が起こるかを説明するためにコメントを埋め込んでいますが、それらの動作はほとんど変わりません。

#include <iostream>

// a simple template class with a public member template struct
template <class Z>
class Pa
{
// anything
public:
    template <class U>
    struct Pe  // a nested template
    {
        // anything
        void f(const char *); // a non-template member function
    };

    template <class U> friend struct Pe;
};

// definition of the function f
template <class AAA>
template <class BBB>
void Pa<AAA> :: Pe<BBB> :: f(const char* c)
{
    Pa<AAA> p; // NO typename for both clang and GNU...

    // the following line is ACCEPTED by both clang and GNU
    // without both template and typename keywords
    // However removing comments from typename only
    // makes clang still accepting the code while GNU doesn't
    // accept it anymore. The same happens if the comments   of template
    // ONLY are removed.
    //  
    // Finally both compilers accept the line when both typename AND
    // template are present...
    /*typename*/ Pa<AAA>::/*template*/ Pe<BBB> q;

    // in the following clang ACCEPTS typename, GNU doesn't:
    /*typename*/ Pa<AAA>::Pe<int> qq;

    // the following are accepted by both compilers
    // no matter whether both typename AND template
    // keywords are present OR commented out:
    typename Pa<int>::template Pe<double> qqq;
    typename Pa<double>::template Pe<BBB>  qqqq;
    std::cout << c << std::endl; // just to do something...
}

int main()
{
    Pa<char>::Pe<int> pp;
    pp.f("bye");
}

では、スコープ内にf依存Pa<double>::Pe<BBB>する名前がありますか?

そしてどうPa<AAA>::Pe<int>ですか?

そして、結局のところ、引用された 2 つのコンパイラーのこのような異なる動作はなぜでしょうか?

誰でもパズルを解くことを明確にすることができますか?

4

1 に答える 1