c++ - 多参数隐式转换、运算符重载

标签 c++ c++11 implicit-conversion

我目前正在阅读“The C++ Programming Language”一书。下面是相关代码

class complex {
public:
  complex(double r, double i): re{r}, im{i} {}
  complex(double r): complex{r,0} {}
  complex(): complex{0,0} {}

  complex& operator-=(complex z) {
    this->re -= z.re;
    this->im -= z.im;
    return *this;
  } 
private:
  double re,im;
};

inline complex operator-(complex a, complex b) {
  return a -= b;
}

inline complex operator-(complex z) {
  return{ 0, 0 } - z;
}

一元operator-给出错误-

syntax error : missing ';' before '-'

但是,编译器认为以下两种变体都是正确的

inline complex operator-(complex z) {
  return 0 - z;
}

inline complex operator-(complex z) {
  return {-z.real(), -z.imag()};
}

我认为在这两种情况下都会发生隐式转换。 那为什么是

inline complex operator-(complex z) {
  return {0,0} - z;
}

标记为错误?

编辑 - 修复 operator-= 函数调用的返回类型,并添加 operator-(),因为它与问题相关。

最佳答案

我假设教科书中的示例也提供了二进制 operator-,因为如果没有它,即使 {0, 0} 是隐式的,代码也无法编译在违规行上转换为 complex

return{ 0, 0 } - z;

此行无法编译的原因是 braced-init-list ({0, 0}) 不是表达式,因此不有一个类型。所以它不能用作二进制 operator- 的操作数之一。

return {-z.real(), -z.imag()}; 起作用的原因是因为标准明确允许它。

§6.6.3/2 [stmt.return]

The expression or braced-init-list of a return statement is called its operand. ... A return statement with any other operand shall be used only in a function whose return type is not cv void; the return statement initializes the object or reference to be returned by copy-initialization (8.5) from the operand.

这种情况下的复制初始化复制列表初始化(§8.5.4 [dcl.init.list])它将考虑 complex(double r, double i) 构造函数,因为它不是显式


operator-= 的返回类型也很奇怪,它修改了complex 实例,但随后返回了一个拷贝。一个典型的实现是

complex& operator-=(complex const& z) {
...
}

关于c++ - 多参数隐式转换、运算符重载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30182097/

相关文章:

java - java中的隐式转换运算符+=

c++ - 混合低级 C/C++ 代码

c++ - 使用 Marmalade 开发 Roku 应用程序的可行性如何?

C++11 "correct"延迟执行方式

c++ - <cstdint> 与 std::size_t 类型

c++ - 存在转换构造函数和运算符并且涉及显式时的行为

c++ - C++ 如何将 int 舍入为 float/double?

c++ - 安全地将字节写入流

c++ - QImage垂直翻转

c++ - Lambda 函数返回类似自动的行为