我使用两个辅助结构来处理智能指针和向量
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)的处理方式不同?
答案 0 :(得分:5)
因为编译器无法推断出(2b)中的类型。问题是它可以匹配
vector<shared_ptr<T>,allocator<shared_ptr<T>>>
因为那只是“只是一种类型”来匹配。对于任何给定的参数,它只检查是否存在T
且类型匹配。编译器只需要测试一个选项。对于
typename Vector<typename Pointer<T>::type>::type
编译器必须尝试所有T
for Vector<...>::type
将产生所需的类型,而不是它。如果可能的话,该分析将比仅匹配直接类型更复杂。