Copy constructor is not called for copy-initialization or optimized?

匆匆过客 提交于 2019-12-04 05:20:19

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!