3

以下のコードは正常に機能します。

template<typename T> class X {};
class A;  // line-1
void foo();  // line-2
int main ()
{
  X<A> vA;
}
class A {};
void foo() {}

line-1とline-2を内部に移動させますmain()。関数は影響を受けませんが、class A前方宣言は機能せず、コンパイラエラーが発生します:

エラー:template<class T> class Xローカルタイプを使用するためのテンプレート引数main()::A

4

2 に答える 2

4

C++ では、関数内でクラスを定義できるため、観察できることが起こっています。したがって、 を配置class A;すると、グローバル スコープ ( ) ではなく、mainこの関数のスコープ (つまり ) でクラスを前方宣言することになります。class main::Aclass A

したがって、最終的に、型 X のオブジェクトを、未定義のクラス ( X<main::A>) のテンプレート引数で宣言しています。

于 2012-10-06T06:32:17.650 に答える
2

エラー: テンプレート クラス X のテンプレート引数はローカル型 main()::A を使用します

これが本当の問題です - ローカル型を使用しています。C++03 では、ローカル型をテンプレート引数として使用することはできません。結果の型に名前を付ける方法を誰も理解していなかったからです。

class Aいくつかのオーバーロードされた関数 (同じ名前を使用している) にいくつかある場合はどうなりますか? 結果のX<A>は同じ型になりますか、それとも異なる型になりますか? どのようにそれらを区別しますか?

C++03 では、標準はこれを通過し、「それをしないでください!」とだけ言いました。

この問題は C++11 で解決されX<A>、ローカル型を使用することは、関数の外側の無名名前空間で宣言されているA場合と同じであると判断されました。A

namespace
{
    class A
    { };
}

int main()
{
    X<A>   vA;
}

そのため、新しいコンパイラ (または-std=cpp11オプションを使用) を使用すると、ローカル クラスを使用でき、その意味もわかります。


ただし、関数内で型を前方宣言しても、別のスコープで型を前方宣言するのと同じ意味ではありません。それらは単に異なるタイプになります。

于 2012-10-06T10:00:35.693 に答える