C++可移动对象 - 赋值运算符应该返回什么?

3

考虑移动赋值运算符的这个规范形式:点击这里

class_name & class_name :: operator= ( class_name && )

当禁用复制时,链接等于不可能,因为返回值是lvalue,从逻辑上讲这没有意义。唯一可以看到(也许您有其他示例)可用的返回值的地方是调用接受class_name参考/常量引用的函数:

void foo(class_name&){}
void bar(const class_name&){}

void use_foo_bar()
{
    some_class a;

    foo(a = get_some_class());
    bar(a = get_some_class());
}

个人认为,这种编程方式不好(个人观点),不希望在代码库中看到这种方式。

当禁用复制时,返回当前对象是否有意义,还是使用void返回类型可以接受?


如果你在链式调用中写入 std::move,那么这是可能的。 - Lightness Races in Orbit
@LightnessRacesinOrbit 那是...调用一个函数 ;) 我不直接使用这个值,我使用它调用一个函数,并使用该函数的返回值。 - Mircea Ispas
1
我真的看不出问题。 - Lightness Races in Orbit
@LightnessRacesinOrbit a = b = get_some_class() 与 a = std::move(b = get_some_class()) 是不同的。 - Mircea Ispas
那么这一切的实用性是什么呢? - Lightness Races in Orbit
2个回答

2

你可以认为链式赋值从来都不是好的选择,应该将operator=的返回类型设为void

但如果你不这么做的话,在编写operator=签名时你需要考虑“这是一个仅可移动类型吗?”这种心理负担,而将所有类型都采用同样的方式会更加简单。

编辑:换句话说,按照通常的方式编写运算符比读者弄清楚你为什么没有这样做要容易得多。


1
在禁用复制或返回类型为void的情况下,返回当前对象是否有意义?
关于operator=是否应该在任何情况下返回已分配的对象或仅返回void存在一般争议。许多人认为允许链接会导致代码可读性降低,并鼓励将多个操作写入一个语句/行中。
我假设您的问题不是哲学上的问题,而是更具实践性的问题。在这种情况下,请考虑某些链仍然可以工作:
auto&& c = a = b;

c 是一个引用(类型为 class_name&),而不是对象,因此从 operator= 返回的左值引用会适当地初始化 c。对于作为引用的函数参数,情况显然也是如此,并且有很多这样的参数:

template <typename T>
void f(T&& t);

// […]

f(a = b);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接