简体   繁体   中英

C++ move only objects - what to return from assignment operator

Considering this canonical form of move assignment operator:

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

When copy is disabled chaining equals is not possible because the returned value is lvalue and from a logical point of view it doesn't make sense. The only place where I can see(maybe YOU have other samples) the returned value usable is when calling a function that accepts a reference/const reference to 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());
}

but I see this as a bad programming style(personal opinion) and I wouldn't like to see it in the codebase.

Does it make sense to return current object when copy is disabled or void return type is ok?

You could argue that chaining is never a good thing and always give operator= a void return type.

But if you don't do that, spare yourself the mental overhead of "Is this a move-only type?" when writing the operator= signature and do it the same way for all types.

Edit: To put it another way, it is less work for you to write the operator in the usual way than it is for readers of your code to figure out why you didn't.

Does it make sense to return current object when copy is disabled or void return type is ok?

There is general debate over the question whether operator= should in any case return the assigned object or just void . Many say that allowing chaining leads to less readable code and encourages to write more than one thing into one statement/line.

I assume your question is less philosophical but more practically orientated. In this case, consider that some chains still work:

auto&& c = a = b;

c is a reference (with type class_name& ), not an object, so the returned lvalue reference from operator= initializes c appropriately. That is obviously also the case for function parameters that are references, and there are quite a lot of them:

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

// […]

f(a = b);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM