【发布时间】:2016-03-27 16:44: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,参数intoverconst int&对Matrix类没有多大帮助(但调用的代理运算符具有交换参数的目标运算符是可以的) - 考虑到(可能的)操作顺序 (
x@y != y@x),两者应该有相同的返回语句 - return 语句应该完全相同,因为给定的
operator@是每个重载operator +=的类
【问题讨论】:
-
为什么不首先按值取参数,而不是 const ref?
-
不知道你在说什么。
-
这个
operator+不是通用的;它传输A类型的对象。没有充分的理由避免使用A类型,因为您确切地知道它是什么。即使在通用代码中,您也会知道您正在处理的类型。所有这些迂回都是毫无意义的。 -
从逻辑上讲是有道理的。您复制
*this并添加到其中。没有什么不对。 @Useless 嗯...大声笑,这太完美了!几乎可以解决它,但我仍然很想知道是否可以在不调用任何其他函数(包括构造函数)的情况下从 const 引用中创建一个非常量临时变量。编辑:嗯,这适用于A@A运算符,但是A+number呢?从数字到 A 的隐式转换完全很糟糕。 EDIT2:此外,当操作 A@B 不等于 B@A 时,这也不起作用。
标签: c++ c++11 operator-overloading c++14