繁体   English   中英

C ++转换运算符和重载决策

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM