基于operator + =的非朋友单行操作符+重载

时间:2016-03-27 16:44:15

标签: c++ c++11 operator-overloading c++14

假设我有一个班级:

class A
{
    //...
};

定义明确operator +=

A& operator +=(const A&) {return *this;} //class without members

所以让我们尝试重载operator+(作为非朋友)。我不想使用类名来调用临时对象的构造函数(有点想做这个通用代码):

A operator +(const A& other) const
{
    return auto(*this)(*this) += other; //error: invalid use of auto
//         /\/\/\/\/\    /\      
//        type of *this  ||
//                 constructor call
}

auto在这里不好。我们试试decltype

A operator +(const A& other) const
{
    return decltype(*this)(*this) += other; //error: 'A& A::operator+=(const A&)' discards
//         /\/\/\/\/\/\/\    /\                      qualifiers [-fpermissive] return
//          type of *this    ||                      decltype(*this)(*this) += other;
//                    constructor call                                      ^
}

这设法从*this中获取了类型,但operator+被声明为const,因此我们推导出const A(这就是我的想法)。让我们继续:

A operator +(const A& other) const
{
    return typename std::remove_const<decltype(*this)>::type(*this) += amount; 
    //same error as previous
}

现在我心烦意乱。即使我认为我删除了constness,它仍然丢弃 预选赛。好吧,也许那是因为我所做的只是铸造。如此愚蠢。要调用构造函数,我必须生成(除了类型)具有:: Constructor的代码(所以我甚至尝试为构造函数创建别名,但此时我失败了很多)。我的破碎的大脑放弃了,但我的意识的其余部分给了我一个解决方案(这是写作的通用,所以这很好):

// outside of class
template<class A>
inline A&& make_rvalue(A copy)
{
    return std::move(copy);
}

// inside of class
A operator +(const A& other) const
{
    return make_rvalue(*this) += other; // such generic code
}

这就是我的结局。但是有一些技巧不涉及任何其他函数调用吗?

编辑:我知道这样做的经典方法,但我搜索的内容如下所述:

  • 运算符缩减为{return /*...*/;}
  • 不涉及类方法或全局函数的名称
  • 考虑了其他类型的重载 - 它不能按值获取参数,因为class A != class B,参数int超过const int&对{{1}没有多大帮助class(但是用交换的参数调用目标操作符的代理操作符是正常的)
  • 考虑(可能的)操作顺序(Matrix),其中两者应具有相同的返回语句
  • 对于给定的x@y != y@x
  • return语句应该是相同的operator@

2 个答案:

答案 0 :(得分:1)

如果您创建这样的函数:

function m(readableStream:NodeJS.ReadableStream, image: string): m.State;

你可以像这样使用它:

template <typename T>
T add(T temp,const T &b)
{
    temp += b;
    return temp;
}

答案 1 :(得分:1)

我要记录下来,说这整条思路/编码都是错误的。您已经知道(在这种情况下)返回类型是A。您的代码似乎在以尽可能最复杂,最间接的方式说A方面付出了很多努力。

A operator +(const A& other) const {
    A ret {*this};
    ret += other;
    return ret;
}

由于您似乎真的想要使用C ++ 11功能(即使在这种情况下几乎没有提供任何真正的帮助)我使用了支撑初始化程序,因此它使用来自C ++ 11的东西。不,这不是一行,但它是可读的。

请注意,通用代码中的相同样式也很好。例如,在operator+的非成员重载中,我们可能会有类似这样的内容:

template <class T>
T operator+(T const &a, T const &b) { 
    T ret {a};
    ret += b;
    return ret;
}

虽然可以简化这一点:

template <class T>
T operator+(T ret, t const &b) { 
    ret += b;
    return ret;
}

同样,我们错误地 nothing ,因为较旧的编译器可以并且将毫无问题地接受代码。