我有一个表示 3D vector 的类。它有一些成员函数(点积、叉积等)和一些重载运算符(+-*/)。我在复杂表达式中使用这些运算符时遇到问题。
在一个简化的测试用例中,如果我将运算符重载为
testclass operator+ (testclass& a, testclass& b) {
return testclass(a.get()+b.get());
}
我可以
testclass a = testclass(3);
testclass b = testclass(4);
testclass c = a + b;
没有问题,但是表达式比较复杂
testclass c = a + b + a + b;
将无法编译。我可以通过将重载函数更改为
来解决问题testclass operator+ (testclass a, testclass b) {
return testclass(a.get()+b.get());
}
然而,这涉及按值传递,据我所知,在第一种情况下,这比按引用传递方案慢。我在一段数学密集型代码中使用此类,而我的真实类包含三个长 double 作为数据成员,因此我怀疑性能影响可能很大。
我的问题是:
- 为什么会发生这种行为?
- 我能否在不求助于按值传递的情况下避免它?
- 当我有 3 个 long double 作为数据成员时,按值传递而不是按引用传递是否会影响性能?优化编译器 (g++ -O3) 会优化它吗?
提前致谢。
准确的编译错误是:
operator_overload.cpp: In function ‘int main()’:
operator_overload.cpp:37:29: error: no match for ‘operator+’ (operand types are ‘testclass’ and ‘testclass’)
testclass c = a + b + a + b;
^
operator_overload.cpp:37:29: note: candidate is:
operator_overload.cpp:30:15: note: testclass operator+(testclass&, testclass&)
testclass operator+ (testclass& a, testclass& b) {
^
operator_overload.cpp:30:15: note: no known conversion for argument 1 from ‘testclass’ to ‘testclass&’
我的完整测试代码如下:
#include <iostream>
class testclass {
public:
testclass();
testclass(int);
int get();
void set(int);
private:
int data;
};
testclass::testclass() {
data = 0;
}
testclass::testclass(int a) {
data = a;
}
int testclass::get() {
return data;
}
void testclass::set(int a) {
data = a;
return;
}
testclass operator+ (testclass& a, testclass& b) {
return testclass(a.get()+b.get());
}
int main () {
testclass a = testclass(3);
testclass b = testclass(4);
testclass c = a + b + a + b;
std::cout << c.get() << std::endl;
return 0;
}
最佳答案
问题是右值不能绑定(bind)到左值引用。 a + b + a + b
中的中间结果,比如说 a+b
,是临时的,完整的表达式无法工作。 OTOH,const 引用可以绑定(bind)到右值。将签名改为testclass operator+ (const testclass& a, const testclass& b)
即可解决。
要使上述签名有意义,您还需要让 testclass::get
成为 const
方法。
关于c++ - 复杂表达式中重载 + 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27630402/