2

次のことがうまくいかない理由を頭に入れようとしています。std :: vectorがあり、それに含まれているvalue_typeの静的メンバー関数を次のように呼び出したいと思います。

std::vector<Vector> v;
unsigned u = v.value_type::Dim();

ここで、Vectorは実際にはテンプレート化された型のtypedefです。

template <typename T, unsigned U> class SVector; 
typedef SVector<double, 2> Vector; //two-dimensional SVector containing doubles

静的メンバー関数Dim()は、実際にはVectorの次元Uをインライン化します。

これで、コンパイラは次のようなエラーメッセージを返します。

 error: ‘SVector<double, 2u>’ is not a base of 
 ‘std::vector<SVector<double, 2u>, std::allocator<SVector<double, 2u> > >

それは私を困惑させます。明らかに問題のある行を次のように置き換えることができます

unsigned u = Vector::Dim();

それは機能しますが、vのvalue_typeに関する仮定をハードコードしているため、明らかに醜いです...ありがとう!

4

1 に答える 1

15

変数タイプではなく、変数インスタンスを介してvalue_typeにアクセスしています。

方法1-これは機能します:

typedef std::vector<Vector> MyVector;
MyVector v;
unsigned u = MyVector::value_type::Dim();

方法2-またはこれ:

std::vector<Vector> v;
unsigned u = std::vector<Vector>::value_type::Dim();

メソッド1のようにtypedefを使用する場合は、ベクトルテンプレートパラメーターの仮定をハードコーディングせず、クリーンなコードを記述します。


編集:質問の所有者からの要求に応じて、この問題の動作を説明するために拡張されました。

スコープ解決演算子::は、他のどのC++演算子よりも優先されます。これには、オブジェクト.演算子からのメンバーアクセスが含まれます。したがって、次のようなものを書くとき:

unsigned u= v.value_type::Dim();

これは、次のC++コードに解決されます。

unsigned u = v.SVector<double, 2>::Dim();

そして最終的に最初に解決されるのはそのSVector<double, 2>::Dim()部分です。これにより、トラフ変数として宣言されたベクターインスタンスvに、SVectorという名前のテンプレート化された内部クラスが強制されます。そして、これは起こらないので、これはエラーになります:

error C2039: 'SVector<double,2>' : is not a member of 'std::vector<_Ty>'

STLvectorは、このパターンを使用するたびに「拡張」する必要があります(変数タイプではなく、変数インスタンスを介してvalue_typeにアクセスします)。これは、多くの定型文と不要で保守不可能なコードにつながるため、適切なソリューションではありません。上記の解決策に従うことで、これをすべて回避し、必要なことを簡単に実行できます。

于 2008-10-13T11:15:34.093 に答える