13
template<int N>
struct S
{
    void foo()
    {
        sizeof( S ); // (*)
        sizeof( S<N> );
    }
};

int main()
{
    S<5> s;
    s.foo();
    return 0;
}

このコードは正常にコンパイルされます (VS2010) が、(*)文字列について疑問があります。S私の意見とは異なりS<N>、完全な型ではありません。なぜコンパイラはそのサイズを知っているのですか? このような状況について、標準は何と言っていますsizeofか?

4

4 に答える 4

15

Sの定義内の名前struct Sは、注入されたクラス名 Sを参照します。これは、14.6.1/2 (C++03) に従って、明示的な引数リストを必要としません。

クラス テンプレートの特殊化または部分的な特殊化のスコープ内で、injected-class-name の後に < が続かない場合、injected-class-name の後にクラス テンプレートの特殊化または部分的な特殊化の template-arguments が続くことと同等です。 <>で囲みます。

スコープ解決演算子を使用して、(注入されたクラス名ではなく) テンプレートの「元の」名前を意図的に使用するようにコンパイラに強制する場合、パラメーター リストは必須になることに注意してください。

template<int N>
struct S
{
    void foo()
    {
        sizeof( ::S );    // <- ERROR
        sizeof( ::S<N> ); // <- OK
    }
};
于 2013-11-07T08:54:13.817 に答える
11

C++ は暗黙的using S = S<N>;にクラス本体に挿入するため、2 つのステートメントは同等です。

template<int N>
struct S {
    static_assert(std::is_same<S, S<N>>(), "");
};

の定義外だとエラーになります。sizeof(S)S

于 2013-11-07T08:45:54.553 に答える
3

テンプレート内では、テンプレート名は注入されたクラス名S<N>でもあり、テンプレートではなくクラス タイプを参照します。クラスメンバー関数内では、関数がクラス内で定義されていても、クラス型は完全です。したがって、どちらも有効であり、互いに同等です。

于 2013-11-07T08:49:34.573 に答える