I understand that the compiler does the copying in the code below, since copy and move constructors are not called in the so-called copy-initialization done in main() . See a live example .
#include <iostream> struct S { S() = default; S(const S&) { std::cout << "copy ctor" << '\n'; } S(S&&) { std::cout << "move ctor" << '\n'; } }; int main() { S s = S(); }
But I cannot understand why the code does not compile when I remove the move constructor, as shown below:
#include <iostream> struct S { S() = default; S(const S&) { std::cout << "copy ctor" << '\n'; } S(S&&) = delete; }; int main() { S s = S(); }
I cannot find anything in §12.8 / 32 (N4140), which could prohibit the use of a constructor in this case. This proposal, which aroused my attention in § 12.8 / 32, which seems to indicate that the copy constructor should have been considered in overload resolution:
If the first overload resolution failed or was not executed, or if the type of the first parameter of the selected constructor is not rvalue refers to the type of objects (possibly cv-qualit), overload resolution is performed again, treating the object as naming.
Edit
From one of TC's comments below, I understand that when the object to be copied is denoted by rvalue, the compiler, according to §12.8 / 32, does not consider the copy-instance as a candidate for the copy, although the copy will be rejected anyway. That is, the end result will be the construction of an object s with a standard constructor. Instead, in this situation, the standard requires (where?) A badly formed code. If my understanding of this scheme is completely wrong, it makes no sense to me.
source share