'Should explicit keyword be used for move constructors?

This code does not compile. But if I remove the explicit keyword from the move constructor then it works. Why?

struct Bar {
    Bar() {}
    explicit Bar(const Bar& x) {}
    explicit Bar(Bar&& x) {}
};

Bar bar() {
    Bar x;
    return x;
}

The compilation error is:

error: no matching function for call to 'Bar::Bar(Bar&)'
c++


Solution 1:[1]

Typically, no. Do you want move-construction to be explicit? If so, yes. Otherwise: no. But typically only converting constructors are explicit. (I occasionally make the copy-c'tor explicit, delete the copy-assignment operator, but leave the move-c'tor implicit when I have a "heavy" class that almost never want to deeply-copy, so users can say Foo(foo) if they want a copy, but they have to think about it.)

Solution 2:[2]

return x; performs copy initialization, which won't consider explicit constructors.

Copy-initialization is less permissive than direct-initialization: explicit constructors are not converting constructors and are not considered for copy-initialization.

BTW for the return statement like return x;, the move constructor of Bar will be considered firstly; then the copy constructor if the move constructor is not appropriate.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Ben
Solution 2