const
来避免不太可能的错误)。const
,你实际上禁用了移动操作*。// T is move assignable, with the usual declaration of a move assignment operator
T f();
const T g();
int main() {
T t;
t = f(); // can move
t = g(); // cannot move!!!
}
由于您返回的是类型为T
的临时rvalue实例,除非赋值操作具有一些全局副作用,例如对T
类型的数据成员是静态变量的修改、输出到终端等等,否则该语句不会执行任何操作。因此,根据类型以及赋值运算符是否为编译器默认赋值运算符,整个操作可能会在优化过程中被安全地省略。如果类型T
有用户定义的赋值运算符,则赋值操作不会被省略,但正如之前提到的,除非存在全局副作用,否则这将超出语句执行的生命周期而不会对c
的值存储在命名和可访问内存位置的对象中。
请注意,如果您将返回类型T
声明为const
,并且您的运算符方法不是const
类方法,则会禁用某些类型的运算符链以及许多其他有用的功能,例如调用具有副作用的方法。例如:
(a+b).print(); //assuming print() is non-const method
假设 operator+
不是一个 const
类方法,则:
d = (a+b) + c;
operator +
实现为成员函数。只需实现operator +=
,它肯定不是const。然后提供一个全局函数来处理operator +
,我认为这是最常见的方法。T& T::operator +=(const T& t)
{
// add t to object ...
return *this;
}
T operator +(T t1, const T& t2)
{
t1 += t2
return t1; // RVO will eliminate copy (or move constructor)
}
T operator+(const T &, const T &);
和const T operator+(const T &, const T&)
之间的性能差异是什么?” - James O'Doherty