【问题标题】:Template conversion operator issue模板转换运算符问题
【发布时间】:2021-08-18 09:13:02
【问题描述】:

我浏览了一下,这是我能找到的最相关的link,但它没有回答我的问题

问题:为什么模板替换失败,下面没有编译?

template <typename T>
struct A
{
   A() {};
   A(T value) : val(value){} 
   operator T() { return this->val;}
   T val;
};


A<std::string> test;
std::cout << "xxx" + std::string(test); //works fine
std::cout << "xxx" + test; //compiler error

错误信息:

error: no match for 'operator+' (operand types are 'const char [4]' and 'A<std::__cxx11::basic_string<char> >')
   19 |    std::cout << "xxx" + test;
      |                 ~~~~~ ^ ~~~~
      |                 |       |
      |                 |       A<std::__cxx11::basic_string<char> >
      |                 const char [4]

【问题讨论】:

  • 不是替换失败。请在问题中包含错误消息
  • Fwiw, static_cast 在这里可以工作,因为它不仅考虑隐式转换(在这里会失败),而且还考虑直接初始化 转换函数(这将工作这里)。 IE。 "xxx" + static_cast&lt;std::string&gt;(test)应该成功。
  • 谢谢@WhozCraig。有没有办法修复模板以适应这种情况?
  • @eucristian Meh。并不真地;至少我不想在代码中写上我的名字。 operator + 的模板好友重载与 operator &lt;&lt; 的好友重载相结合可以做到这一点,但天哪。后者可以通过@songyuanyao 在他的回答评论中显示的方法来避免。

标签: c++ templates type-conversion implicit-conversion


【解决方案1】:

std::operator+(std::basic_string)是一组操作符模板,需要对第二个操作数test进行模板实参推导。但在template argument deduction 中不会考虑隐式转换(从A&lt;std::string&gt;std::string)。

类型推导不考虑隐式转换(除了上面列出的类型调整):这是重载解析的工作,稍后会发生。

正如您所展示的,像"xxx" + std::string(test); 这样的显式转换可以正常工作。您还可以显式指定模板参数(以丑陋的方式)以绕过模板参数推导。

operator+ <char, std::char_traits<char>, std::allocator<char>>("xxx", test);

【讨论】:

  • 谢谢你。有什么好的技术/建议来纠正模板以适应这种情况?
  • @eucristian 我认为直接为A 定义operator+
  • @eucristian 没有真正正确的方法可以做到这一点。您可以编写一个运算符来接受“可以转换为 std::string 的任何内容”+“可以转换为 std::string 的任何内容”,但这会很快产生其他歧义问题。 std::string{"xxx"} + test 也可以,但要求编译器转换两个参数以找到匹配项通常过于贪婪。
  • @super std::string{"xxx"} + test 仍然无法工作,因为 test 上的模板参数推导失败。
  • @eucristian 例如this.
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-12-06
  • 1970-01-01
  • 2020-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-11
相关资源
最近更新 更多