'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&)'
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 |
