编译器拒绝两个相同的模板特化

时间:2013-03-25 12:50:57

标签: c++ templates stl typedef template-specialization

我使用两个辅助结构来处理智能指针和向量

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

产生真实。但是我现在有一个模板化的函数(实际上是一个oparator),在使用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)时,调用此运算符按预期工作。但是,当我用(2b)替换(2a)时,编译器/链接器会尝试将调用与(1)匹配,这会为我产生链接错误,因为(1)没有为向量定义/有效。为什么编译器对(2a)和(2b)的处理方式不同?

1 个答案:

答案 0 :(得分:5)

因为编译器无法推断出(2b)中的类型。问题是它可以匹配

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

因为那只是“只是一种类型”来匹配。对于任何给定的参数,它只检查是否存在T且类型匹配。编译器只需要测试一个选项。对于

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

编译器必须尝试所有T for Vector<...>::type将产生所需的类型,而不是它。如果可能的话,该分析将比仅匹配直接类型更复杂。