19

挿入されたクラス名についてC++標準で読んだことは、(私が見ているように)サンプルプログラムの動作と矛盾しています。これが私が読んだものです:

  • 3.4から(パラグラフ3)

    クラスの注入されたクラス名(第9節)も、名前の非表示と検索の目的で、そのクラスのメンバーであると見なされます。

  • 9から(段落2)

    クラス名は、クラス名が表示された直後に宣言されているスコープに挿入されます。クラス名は、クラス自体のスコープにも挿入されます。これは、注入されたクラス名として知られています。アクセスチェックの目的で、注入されたクラス名は、パブリックメンバー名であるかのように扱われます。

これらのことから、以下は整形式の翻訳単位であり、正常にコンパイルされることがわかります。

#include <vector>
class X: std::vector<int>
{
   vector mem;
};

ただし、次の場合はエラーが発生するはずですが、そうではありません。

#include <vector>
class X: std::vector<int>, std::vector<char>
{
   vector mem; //compiles OK... mem is apparently std::vector<int>
};

名前は両方にvector挿入され、パブリックメンバー名のように挿入されるため、Xに継承される必要があります。したがって、の名前はあいまいである必要があります。私は何かが足りないのですか?std::vector<int>std::vector<char>vectorX

PS私はMSVC9.0を使用しています

4

2 に答える 2

17

見つけた!それは標準でまさにそこにあります!私は正しかったです!あいまいなはずです!

14.6.1項

インジェクトされたクラス名(10.2)を見つけるルックアップは、特定の場合(たとえば、複数の基本クラスで見つかった場合)にあいまいさをもたらす可能性があります。見つかったすべての注入されたクラス名が同じクラステンプレートの特殊化を参照し、名前の後にtemplate-argument-listが続く場合、参照はクラステンプレート自体を参照し、その特殊化は参照しません。あいまいではありません。[例:

template <class T> struct Base { };
template <class T> struct Derived: Base<int>, Base<char> 
{ 
    typename Derived::Base b; // error: ambiguous typename 
    Derived::Base<double> d;  // OK 
};

-例を終了]

結論:これはさらに別のMicrosoftコンパイラのバグです。言語拡張機能を無効にしても役に立ちません。

于 2011-08-11T11:55:56.423 に答える
4

いいえ、何も見逃していません。コンパイラはバグのある動作をしているようです。gccがそれをどのように処理するかをここで見ることができます:http://ideone.com/MI9gz

そのエラーメッセージは次のとおりです。

prog.cpp:4:4: error: reference to 'vector' is ambiguous
/usr/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/bits/stl_vector.h:171:5: error: candidates are: class std::vector<char> std::vector<char>::vector
/usr/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/bits/stl_vector.h:171:5: error:                 class std::vector<int> std::vector<int>::vector
于 2011-08-11T11:52:21.113 に答える