21

C ++ 11のローカルクラスの使用法に変更はありますか?

C ++ 03では、ローカルクラスをテンプレート引数として使用できないようです(覚えています)。

このコードを考えてみましょう。

template<typename T> void f(const T&) {}

//Note : S is a local class defined inside main()
int main() { struct S{};  f(S()); } //I want template argument to be deduced.

ただし、コンパイルエラー(C ++ 03モード)が発生し、(ideone)と表示されます。

prog.cpp:4:エラー:「f(main():: S)」の呼び出しに一致する関数がありません</ p>

ただし、C ++ 11モード( ideone )でコンパイルすると正常にコンパイルされます。これは私には理にかなっています。そうしないと、ラムダが機能しません。したがって、ローカルクラスの使用法には少なくともこの変更があると思います。私は正しいですか?ローカルクラスに関するその他の変更点は何ですか?

読者が自分自身を比較できるように、また将来の参考のために、標準(C++03とC++11の両方)から関連するテキストを引用してください。

4

3 に答える 3

12

両方の規格で§14.3.1/2を比較すると、違いがわかります。

  • C ++ 03

    ローカル型、リンケージのない型、名前のない型、またはこれらの型のいずれかから複合された型は、テンプレート型パラメータのテンプレート引数として使用してはなりません。[例:

    template <class T> class X { /* ... */ };
    void f()
    {
     struct S { /* ... */ };
     X<S> x3;        // error: local type used as template-argument
     X<S*> x4;        // error: pointer to local type used as template-argument
    }
    

    —end example] [注:テンプレートタイプの引数は不完全なタイプ(3.9)である可能性があります。]

  • C ++ 0x(n3290)

    [ 例:

    template <class T> class X { };
    template <class T> void f(T t) { }
    struct { } unnamed_obj;
    
    void f() {
     struct A { };
     enum { e1 };
     typedef struct { } B;
     B b;
     X<A> x1;        // OK
     X<A*> x2;       // OK
     X<B> x3;        // OK
     f(e1);          // OK
     f(unnamed_obj); // OK
     f(b);           // OK
    }
    

    —終了例] [注:テンプレートタイプの引数は、不完全なタイプ(3.9)である可能性があります。—エンドノート]

C ++ 03は、テンプレート型引数のローカルクラスを明示的に禁止します。C ++ 11には含まれていません。また、そのような有効な使用例も含まれています。

于 2011-11-20T19:07:30.653 に答える
10

古い標準から:

(14.3)ローカル型、リンケージのない型、名前のない型、またはこれらの型のいずれかから複合された型は、テンプレート型パラメータのテンプレート引数として使用してはなりません。

C++11規格では削除されているようです。

その他の制限:

(9.8)ローカルクラスの宣言では、型名、静的変数、外部変数と関数、および囲んでいるスコープの列挙子のみを使用できます。

(9.8)ローカルクラスはメンバーテンプレートを持たないものとします。

(14.5.4)フレンドテンプレートはローカルクラスで宣言してはならない。

(9.4.2)ローカルクラスは静的データメンバーを持たないものとします。

(9.3)ローカルクラス(9.8)のメンバー関数にはリンクがありません。

于 2011-11-20T18:59:00.410 に答える
2

私自身の質問によると、制限は削除され、ローカルクラスをテンプレート引数として使用できます。
しかし、新しい標準への言及は見当たりません。

于 2011-11-20T18:54:14.717 に答える