2

VS 2008は、他のコンパイラとは少し異なる方法で継承を使用してクラステンプレートを処理しているようです。次のコードは、VS 2008(デフォルトオプションあり)でエラーなしでコンパイルされます。

template <typename S, typename T>
class someclass : public non_existent_class
{
T operator() (S s) const {
    return T(s);
}
};

質問は、なぜですか?識別子が定義されていないため、他のコンパイラはこれを実行できませんでした(GCC 4.5.0、Intel、Online Comeau、VS 2005を試してみました)non_existent_class。多分それはこの振る舞いを正当化する新しいC++0x標準の何かですか?

4

3 に答える 3

1

これは、Visual Studioが2フェーズを実行することになっているときに、単一フェーズの名前ルックアップを実行するという事実の結果である可能性が最も高いです。非依存名「non_existent_class」は、最初のフェーズで失敗する必要があります。これは、テンプレートがインスタンス化されているかどうかに関係なく、定義の時点で発生します。

これはバグですが、MSがテンプレートに対するコンパイラの動作を根本的に変更するまで、修正されることはありません。

http://womble.decadent.org.uk/c++/template-faq.html#two-phase

http://blog.llvm.org/2009/12/dreaded-two-phase-name-lookup.html

于 2011-03-04T20:22:31.453 に答える
0

Visual Studioのコンパイラは、その標準への準拠で有名になることはありませんでした。これはさらに別のバグであるに違いありません。報告すると、もっと重要なことがあると言われます。言うまでもなく、クラスをインスタンス化すると、コンパイラはエラーを発行します。

はい、インスタンス化の前にコンパイラが診断できないものがあります。これは彼らの数には含まれておらず、コンパイラーは診断を発行する必要があります。C++0xはこのルールを変更しません

于 2011-03-04T19:12:07.107 に答える
0

コンパイラがそのコードを受け入れ、他のコンパイラが受け入れないと言うとき、それはそのコードの一部を意味するのでしょうか、それともテンプレートをインスタンス化するのでしょうか?

テンプレートは、定義が検出されたときにコンパイルされるのではなく、インスタンス化されたときにコンパイルされます。テンプレートをインスタンス化していない場合は、コンパイラがテンプレート定義全体を完全に無視している可能性があります(テンプレート定義がいつ終了するかを知るために十分なコードを解釈できる必要があるため、可能な限り) )。

その後、テンプレートが実際にインスタンス化され、テンプレートに特殊化がないと仮定すると、コンパイラは文句を言います。特定のタイプにスペシャライゼーションを提供する場合、そのスペシャライゼーションは同じ存在しないクラスから継承する必要がないことに注意してください。

この特定のケースでは、これは、Microsoftコンパイラが依存する名前に対して行う特別な(非標準のように)扱いによるものだと思う傾向があります。テンプレート内の依存名の前に指定する必要がないのと同じようにtypename(基本クラス、またはこのテンプレートの型引数を使用した別のテンプレートのインスタンス化を考えてください)、コンパイラーは次のことを考慮している可能性があります。基本クラスは、実際のインスタンス化が行われる前に定義され、その瞬間を待って検証を実行します。

于 2011-03-04T19:54:54.263 に答える