3

g++ を使用して Microsoft Visual C++ コードをコンパイルしようとしています。今、私は本当に理解できないコンパイラエラーに遭遇しました。(簡略化された) コードは次のようになります。

template<int X> struct A {
    template<class Ret> static Ret call() {
        return 0;
    }
};

template<int X> struct B : A<X> {
    int f() {
        return A<X>::call<int>();
    }
};

これを g++ (バージョン 4.4.5) でコンパイルしようとすると、次のエラーが発生します。

main.cpp: In member function int B<X>::f(): 
main.cpp:16: error: expected primary-expression before int 
main.cpp:16: error: expected ; before int
main.cpp:16: error: expected unqualified-id before > token

メソッド A::call からテンプレート型 (Ret) を削除すると、コードは正常にコンパイルされます。ここで何が問題なのか誰にもわかりますか?

ありがとう!

4

3 に答える 3

5

template次のキーワードが必要です。

return A<X>::template call<int>();

callは従属名です。つまり、その意味はテンプレート パラメーターに依存します。これは、コンパイラが処理するときには不明f()です。キーワードcallを前に付けて、それが関数テンプレートであることを示す必要があります。template

ネストされた型にアクセスしようとすると、同じことが起こります。typename名前が型を示すことを示すキーワードを追加する必要があります。

template <typename T>
struct A { typedef int type; };

template <typename T>
void f()
{
    typename A<T>::type i = 0; // notice "typename" here
}

また、両方を混在させる必要がある場合もあります。

template <typename T>
struct A
{
    template <typename U>
    struct inner { };
};

template <typename T>
void f()
{
    typename A<T>::template inner<int> var;
}

これら 2 つのキーワードの使用については、次の質問への回答で詳しく説明されています。(リンクを見つけてくれた@BjörnPollexに感謝します)。

于 2012-01-25T13:58:01.967 に答える
5

Aはテンプレートであり、知らなけれXばコンパイラは の内容を判断できませんA<X>call特に、それがテンプレートになることを知りません。

コンパイラにそれを伝えるには、次のtemplateキーワードを使用する必要があります。

template<int X> struct B : A<X> {
    int f() {
        return A<X>::template call<int>();
    }
};
于 2012-01-25T13:58:46.777 に答える
3

テンプレート クラスの一部であるため、呼び出している関数がテンプレートであることを指定する必要があります。コンパイラは、与えられA<X>たテンプレート関数に という名前が付けられていることを認識していないcallため、それを支援する必要があります。

template<int X> struct B : A<X> {
    int f() {
        return A<X>::template call<int>();
    }
};
于 2012-01-25T14:00:01.653 に答える