RVO and remote move constructor in C ++ 14

I have been studying (N) RVO for the past few days. Since I read about cppreference in a copy article, for C ++ 14:

... compilers are allowed, but it is not necessary to omit the construction of objects of the copy- and move- class (starting with C ++ 11), even if the copy / move constructor (starting with C ++ 11) and the destructor have observable side effects. This is optimization: even when this happens and copy / move-constructor is not called, it should still be present and accessible (as if optimization had not been performed at all), otherwise the program will be poorly formed.

So, any instance or should be available and available. But in the following code:

#include <iostream> class myClass { public: myClass() { std::cout << "Constructor" << std::endl; } ~myClass() { std::cout << "Destructor" << std::endl; } myClass(myClass const&) { std::cout << "COPY constructor" << std::endl;} myClass(myClass &&) = delete; }; myClass foo() { return myClass{}; } int main() { myClass m = foo(); return 0; } 

The following error occurred: test.cpp: In function 'myClass foo()': test.cpp:15:17: error: use of deleted function 'myClass::myClass(myClass&&)' return myClass{}; . I get this error even if I do not call foo() from main() . The same problem with NRVO.

Therefore, you always need a move constructor, right? (while there is no copy, I checked it)

I do not understand where the compiler needs a move constructor. I just assume that this might be needed to create a temporary variable, but that sounds dubious. Does anyone know the answer?

About the compiler: I tried it on the g ++ and VS compilers, you can check it online: http://rextester.com/HFT30137 .

PS I know that in the C ++ 17 standard, RVO is required. But there is no NRVO, so I want to study what is going on here to understand when I can use NRVO.

+5
source share
1 answer

Cited by cppreference :

Remote Functions

If the special syntax = delete; is used instead of the body of the function, the function is defined as deleted.

...

If a function is overloaded, overload resolution is first executed, and the program is only poorly formed if a remote function is selected.

This is not the same if you explicitly define the move constructor to delete. Here, due to the presence of this remote move constructor, although the copy constructor may match, the move constructor is better, so the move constructor is selected when overload resolution is enabled.

If you delete the explicit delete , then the copy constructor will be selected and your program will be compiled.

+6
source

Source: https://habr.com/ru/post/1275151/


All Articles