模板函数模糊参数推导为0

时间:2016-10-07 09:35:13

标签: c++ templates template-deduction

编译以下示例时,我遇到了一个奇怪的问题。

template<typename T>
struct identity {
    typedef T type;
};

template<typename T>
void foo(typename identity<T>::type v) {}

template<typename T>
void foo(typename identity<T>::type* v) {}

int main() {
    foo<int>(0);
    foo<short>(0);
    return 0;
}

调用foo<int>(0)编译,但是,当我调用foo<short>(0)时,编译器无法推断出0是值还是指针。我使用identity强制显式指定模板参数。编译器(msvc)错误消息:

error C2668: 'foo': ambiguous call to overloaded function

是编译器错误吗?

1 个答案:

答案 0 :(得分:3)

编译器错误。这是因为将0转换为指针类型具有“转换等级”。

C ++11§4.10(转换排名)

  

空指针常量是一个整数文字(2.13.2),其值为零   或者类型为std :: nullptr_t的prvalue。空指针常量可以是   转换为指针类型;结果是空指针值   该类型并且可以与对象的每个其他值区分开来   指针或函数指针类型。这种转换称为null   指针转换。

因此,当您编写0字面值并且需要转换时,编译器会遇到两个类似等级的重载 - 一个是非指针类型,另一个是指针类型。

更多例子:

 foo<short>((short)0); // No conversion necessary: allowed
 foo<nullptr_t>(nullptr); // No conversion necessary: allowed
 foo<nullptr_t>(0); // ambiguous
 foo<nullptr_t>(NULL); // ambigious - another reason to stop using NULL