为什么在完美转发中不允许隐式转换?

Mik*_*ipa 4 c++ implicit type-conversion

假设我们有以下代码:

void ff(wchar_t*)
{

}

template<typename T>
void ffc(T&& a)
{
    ff(std::forward<T>(a));
}
Run Code Online (Sandbox Code Playgroud)

为什么ff(0)允许通话,但ffc(0)不是?

Sha*_*our 5

ffc(0)T 的情况下,将推断为int, 因为0是一个整数文字,其类型为int,即使没有转发,也没有从int到wchar_t*的有效隐式转换,因此以下情况也不起作用:

template<typename T>
void ffc_no_forward(T&& a)
{
    ff(a);
}
Run Code Online (Sandbox Code Playgroud)

而在第一种情况下0是一个空指针常量,因此是完全有效的转换为wchar_t*.

我们可以从草案C++ 14 standard(N4140)节中看到4.10指针转换[conv.ptr],一个零值的int是不够的,它必须是一个整数文字,或者必须是std :: nullptr_t的prvalue :

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

在C++ 11中,措辞允许一个整数常量表达式,其被评估为零,但在这种情况下实际上并不重要,因为TC指出std::forward<T>()不能是一个常量表达式,因为函数的参数也不能是常量表达式.