问题
If copy constructor is made private
then in
Case 1: No error, the compiler doesn't care if the copy constructor was defined in class.
Case 2: Error, copy constructor is private and when it is made public
, it is elided.
Does it directly optimizes the copy without being noticing that if the constructor was made private
?
#include <string>
using std::string;
class T
{
string s;
T(const T &obj):s(obj.s){}
public:
T(const string &str):s(str){}
};
int main()
{
T a = ("Copy Initialization"); //Case: 1
T b = T("Copy Initialization"); //Case: 2
}
回答1:
Case 2 comes under 12.8/31 in N3225:
A program is ill-formed if the copy/move constructor or the copy/move assignment operator for an object is implicitly odr-used and the special member function is not accessible.
Just because the copy ctor is elided doesn't mean it isn't odr-used. 3.2/2:
A member of a set of candidate functions is odr-used if it is selected by overload resolution when referred to from a potentially-evaluated expression. [Note: this covers calls to named functions (5.2.2), oper- ator overloading (Clause 13), user-defined conversions (12.3.2), allocation function for placement new (5.3.4), as well as non-default initialization (8.5). A copy constructor or move constructor is odr-used even if the call is actually elided by the implementation. —end note ]
Beware of course that MSVC is not fully C++0x-compliant, because (a) C++0x isn't a standard yet, and isn't finalized; and (b) MSVC hasn't implemented everything up to date anyway. But this stuff isn't substantially changed from C++03, so I'm fairly confident the explanation still holds.
Case 1 would come under this too, except that on the two C++03 compilers I've checked it doesn't get that far because there's no possible conversion from a string literal to T. I can't be bothered to check whether there are any additional conversion sequences allowed in C++0x, there could be a new clause anywhere :-)
It's still a mystery to me why MSVC allows case 1 ever, even with a public copy ctor. Does it allow it in strict C++03 mode?
回答2:
Case 1: No error, the compiler doesn't care if the copy constructor was defined in class.
T a = ("Copy Initialization");
should give an error because there's no suitable constructor to convert from "const char [20]"
to "T"
Did you mean T a = std::string("Copy Initialization");
?
Does it directly optimizes the copy without being noticing that if the constructor was made private?
No it can't. Compilers usually perform syntactic and semantic analysis prior to the code optimization phase.
来源:https://stackoverflow.com/questions/4639576/copy-constructor-is-not-called-for-copy-initialization-or-optimized