5

現在の C++ コンパイラ (最新の gcc、clang) ではtypename、次の例のキーワードが必要です。

template<class T>
struct A
{
};

template<class T>
void f(T)
{
    struct C
    {
    };
    typedef typename A<C>::Type Type; // typename required
}

を省略した場合typename、gcc (4.9、5.0) は次のエラーを報告します。

need 'typename' before 'A<f(T)::C>::Type' because 'A<f(T)::C>' is a dependent scope

この例は、私の C++11 標準の読み方によれば、整形式です。

この動作は、次の文言でカバーされているようです。

[温度依存タイプ]/8

ある場合、型は従属です。

  • テンプレートパラメータ、

  • 未知の専門分野のメンバー、

  • 現在のインスタンス化のメンバーであるネストされたクラスまたは列挙、

  • cv 修飾されていない型が依存している cv 修飾された型、

  • 任意の依存型から構築された複合型、

  • 任意の依存型から構築された配列型、または値依存の定数式によってサイズが指定された配列型、

  • テンプレート名がテンプレート パラメータであるか、いずれかのテンプレート引数が依存型または型依存または値依存の式である simple-template-id、または

  • decltype(expression) で示されます。式は型に依存します。

ただし、[class.local] によると、クラスCネストされたクラスではなくローカルクラスです。もしそうなら、なぜ依存として扱われなければならないのですか?A<C>

編集

ボーナス ポイントについては、次のようにメンバー列挙型を追加して例を変更するとC、次のようになります。

template<typename T>
struct A
{
    typedef T Type;
};

template<class T>
void f(T)
{
    struct C
    {
        enum { value = T::value };
    };
    typedef typename A<C>::Type Type; // typename required
}

A<C>依存として扱われるべきですか?

4

3 に答える 3

0

typenameここでキーワードが必要であると述べている標準には何もないようです。言葉遣いはそれ以外のことを明示的に述べていないため、GCC がf<T>(T)::C(関数テンプレートの特殊化のローカル クラスであることを) 依存として処理する際に少し近道をするようになったT可能性がありA<[f<T>(T)::]C>::Typeます。

コア欠陥 1484は、この問題に対して具体的に提起されたわけではありませんが、それが提案する追加の非規範的なテキストは意図を明確にし、それが標準に含まれていれば、GCC は準拠してtypenameここでキーワードを要求しないと思います。

于 2014-12-29T13:31:43.500 に答える