为何Bjarne教材中complex类的一元operator-返回初始化列表?
为什么
operator-(complex a)返回{-a.real(), -a.imag()}是合理的? 好问题!这个写法看起来有点简洁过头,但其实完全符合C++的语法规则,背后是列表初始化(List Initialization)的特性在起作用。让我们结合你给出的complex类定义来一步步拆解:
1. 先看complex类的构造函数匹配
你提供的complex类里有一个关键的构造函数:
complex(double r, double i) :re{r}, im{i} {} // 接受两个double的构造函数
这个构造函数的作用是用两个标量(实部和虚部)初始化一个复数对象。
当你在返回语句中写{-a.real(), -a.imag()}时,编译器会自动把这个花括号列表和complex类的构造函数做匹配:
- 列表里的两个元素都是
double类型(因为real()和imag()返回double) - 正好匹配
complex(double, double)这个构造函数
所以编译器会隐式地用这两个值构造一个临时的complex对象,作为operator-的返回值。
2. 这是C++的语法糖,等价于显式构造
你完全可以把这个返回语句写成更 verbose 的形式:
return complex(-a.real(), -a.imag());
而用{-a.real(), -a.imag()}的写法只是一种更简洁的语法糖,语义和显式构造完全一致。C++11及以后支持这种列表初始化的写法,目的是让代码更紧凑易读。
3. 为什么不会有歧义?
在这个场景下,编译器不会混淆构造函数的选择:
complex类没有定义接受std::initializer_list<double>的构造函数(如果有的话,编译器会优先选择它)- 列表里的元素数量和类型刚好唯一匹配
complex(double, double)构造函数
所以这个写法是明确且无歧义的。
4. 效率上的考量
这种写法返回的是一个临时complex对象,现代编译器会通过**返回值优化(RVO)**消除临时对象的拷贝开销,所以效率和显式构造完全一样,不会有性能损失。
内容的提问来源于stack exchange,提问作者zell
相关产品推荐
相关产品推荐

