C++ 没有中间对象的操作赋值

C++ 没有中间对象的操作赋值,c++,C++,对于这样一个类: class Vec{ int comp[2]; public: void add(Vec& vec, Vec& vec2){ comp[0] = vec.comp[0] + vec2.comp[0]; comp[1] = vec.comp[1] + vec2.comp[1]; } Vec operator+ (Vec& vec){ Vec res; res.comp[0] = comp[0] + vec.c

对于这样一个类:

class Vec{
  int comp[2];
public:
  void add(Vec& vec, Vec& vec2){
    comp[0] = vec.comp[0] + vec2.comp[0];
    comp[1] = vec.comp[1] + vec2.comp[1];
  }
  Vec operator+ (Vec& vec){
    Vec res;
    res.comp[0] = comp[0] + vec.comp[0];
    res.comp[1] = comp[1] + vec.comp[1];
    return res;
  }
};
有两个成员函数基本上做相同的事情,即将两个
Vec
s相加。当然,不同之处在于,
add
函数中没有中间值,而
operator+
声明了
Vec
的本地对象

我的问题是,有没有办法将
operator+
operator=
结合起来定义为与
add
具有相同的语义,没有中间值?其基本原理是减少所涉及的中间值的数量,以提高效率,同时保持
运算符
语法的优雅

GMP库的C++接口显然可以做到这一点:

该实现的一个重要特性是,像a=b+c这样的表达式会导致对相应的mpz_add的单个调用,而不会对b+c部分使用临时函数


我想知道是否有一些可能的方法可以做到这一点,或者GMP必须为此使用某种解决方法吗?

那么
操作符+=
如何,然后您将其用作
myVec+=otherVec

我看不出这有什么真正的好处,因为您的对象非常小。但对于动态分配的大型向量,这可能是有用的

实现它的一种方法是创建一个临时noop类来保存未赋值的表达式。该类可以转换为Vec,因此对用户来说是透明的。关键是您现在可以为add表达式创建一个专门的操作符。一些代码(填补空白):


这就是GMP的实际作用。但是使用大量宏和模板可以减少代码的重复性。

这是个坏主意,因为它违反了大多数人对操作符行为的自然假设

不幸的是,它也是非常重要的(特别是对于像
gmpxx
这样的库,它们希望提供使用运算符的自然代码、高性能,并且有巨大的对象作为参数)。他们如何做到这一点?通过使用表达式模板,它们可以在编译时优化表达式。其思想是,运算符不直接返回值,而是返回表达式类的具体实例,然后可以使用元编程对这些实例进行操作

表达式模板是一个相当高级的主题,您应该相对确定它将给您的代码带来显著的好处。在您的示例中,向量的大小根本不够相关


我也想要
c=a+b
。定义两者。为了获得额外的分数,请根据
操作符+=
定义
操作符+=
如下:
Vec操作符+(Vec&rhs){Vec temp;temp+=rhs;return temp;}
使添加这两个操作符变得非常容易,没有代码重复,使您的类非常好用。。。一般来说,这只是一个好习惯;)一般来说,如果人们能够使用
a=a+b
,但不能使用
a+=b
,那就有点令人困惑了——除非有充分的理由不同时使用这两种语言,否则这只会使类的使用更加直观。他们使用表达式模板。请看一下代码:
struct VecAdd;
struct Vec
{
    Vec& operator=(const VecAdd& vecadd) { /*...*/ }
};

struct VecAdd
{
    const Vec& v1;
    const Vec& v2;
    operator Vec() { return Vec(/*...*/); } // for things like: f(v+u);
};

VecAdd operator+(const Vec& a, const Vec& b) { return VecAdd{a, b}; }