[英]C++ conversion operator and overload resolution
鉴于此示例,其中包含一些重载:
#include <iostream>
class T
{
public:
operator const wchar_t *(void) const
{
std::cout << "Conversion" << std::endl;
return L"Testing";
}
};
template <class Elem>
class A
{
};
template <class T>
void operator <<(A<T> &, const T *)
{
std::cout << "1" << std::endl;
}
template <class T>
void operator <<(A<T> &, const void *)
{
std::cout << "2" << std::endl;
}
int main(void)
{
A<wchar_t> test;
T source;
test << L"1";
test << static_cast<const wchar_t *>(source);
test << source;
}
它的输出:
1
Conversion
1
Conversion
2
我的问题是 - 为什么要为语句test << source;
调用void operator <<(A<T> &, const void *)
test << source;
? 任何人都可以引用涵盖此案例的标准的特定部分吗?
因为模板参数推导不会考虑用户定义的隐式转换。 结果就是当你写道:
test << source;
,编译器无法为第一个函数模板找到合适的T
; 它试图找到一个T
,使得T const*
与你的T
具有相同的类型,这是不可能的。 参数推断失败,并且没有将模板的实例化添加到重载集。 由于第二个函数模板的第二个参数中没有模板参数,因此没有参数推断失败,并且生成的实例化成为重载集的唯一成员,因此最终被选中。
它使用T
的隐式转换为wchar_t
。 任何类型都可以转换为void*
因此编译器会调用该operator<<
版本。 T*
运算符从来都不是候选者,因为无法从T
隐式获得T*
。 你的意思是让它成为T&
<<
运营商吗?
模板参数的隐式推导不会考虑用户定义的隐式转换。 因此,调用template <class T> void operator <<(A<T> &, const T *)
会将T
从第一个参数推导为wchar_t
,但第二个参数是T
而不是const wchar_t*
。 因此编译器将无法匹配该运算符。
对于template <class T> void operator <<(A<T> &, const void *)
,问题看起来不同: T
将从第一个函数参数推断为wchar_t
。 第二个参数可以通过用户定义的转换隐式转换为const wchar_t*
,然后可以通过转换构建将其隐式转换为const void*
。 因此,此函数可以使用这些参数调用并使用,因为无法推导出另一个函数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.