1

スマートポインターとベクトルを操作するために2つのヘルパー構造体を使用しています

template<typename T>
struct Pointer {
    typedef shared_ptr<T> type;
};

template<typename T>
struct Vector {
    typedef vector<T, allocator<T>> type;
};

この場合、式が

is_same<
    vector<
        shared_ptr<T>,
        allocator<shared_ptr<T>>>,
    Vector<
        Pointer<T>::type>::type>
::value

trueを生成します。ただし、テンプレート化された関数(実際にはオペレーター)があります。これは、使用時Vector<Pointer<T>::type>::typeまたは通常の場合とは異なる方法で処理されvectorます。

// (1) General version
template<typename T>
Foo& operator&(T& object);

// (2a) Specialized version
template<typename T>
Foo& operator&(vector<shared_ptr<T>, allocator<shared_ptr<T>>>& object);

// (2b) Specialized version which does not work
template<typename T>
Foo& operator&(typename Vector<typename Pointer<T>::type>::type& object);

コードに(2a)が含まれているときにこの演算子を呼び出すと、期待どおりに機能します。ただし、(2a)を(2b)に置き換えると、コンパイラー/リンカーは呼び出しを(1)と一致させようとします。これにより、(1)がベクトルに対して定義されていない/有効でないため、リンクエラーが発生します。コンパイラが(2a)と(2b)を異なる方法で処理するのはなぜですか?

4

1 に答える 1

5

コンパイラは(2b)の型を推測できないためです。問題は、それが一致することができるということです

vector<shared_ptr<T>,allocator<shared_ptr<T>>>

それは「単なるタイプ」であるためです。任意のパラメータについて、が存在Tし、タイプが一致するかどうかをチェックするだけです。コンパイラがテストしなければならないオプションは1つだけです。にとって

typename Vector<typename Pointer<T>::type>::type

Tコンパイラーは、必要な型に生成されるためにすべてを試行Vector<...>::typeする必要がありますが、それは実行されません。その分析は、可能であれば、直接型を照合するよりもはるかに複雑になります。

于 2013-03-25T12:55:18.207 に答える