使用运算符<<时出错使用隐式转换的非基本数据类型

时间:2018-06-14 17:49:35

标签: c++ template-deduction

我有一个结构作为其他类型的包装器,如下所示:

template<typename T>
struct A {
  A& operator=(const T& value){
    m_value = value;
    return *this;
  }

  operator T() const {
    return m_value;
  }

private:
  T m_value;
};

我这样用:

int main() {
  A<int> a;
  a = 5;                  // Copy assignment constructor
  std::cout << a << "\n"; // Implicit conversion to int
}

按预期工作。使用非基本类型时会出现问题,如下例所示:

int main() {
  A<std::complex<int>> c;
  c = std::complex<int>(2, 2);  
  std::cout << c << "\n";
}

上面的代码段会引发invalid operands to binary expression错误。

为什么会出现此错误?为什么<<的重载运算符std::complex<int>与隐式转换的A<std::complex<int>>一起使用?

1 个答案:

答案 0 :(得分:6)

std::complex的流运算符是模板函数。除非您实际拥有std::complex,否则不会调用它们,因为模板参数扣除中不会发生转换。这意味着编译器将找不到合适的重载来打印A<std::complex<int>>

你是第一个工作案例,因为std::basic_ostream::operator <<被重载以获取int并允许一个用户定义的转换是重载解析。

作为一项工作,您可以定义自己的operator <<,它将您的包装器转发到基础类型“operator <<。那看起来像是

template<typename T>
std::ostream& operator <<(std::ostream& os, const A<T>& a)
{
    return os << static_cast<T>(a);
}