不为复制初始化或优化调用复制构造函数? [英] Copy constructor is not called for copy-initialization or optimized?

查看:120
本文介绍了不为复制初始化或优化调用复制构造函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果复制构造函数为 private ,则在



案例1:

情况2:错误,复制构造函数是私有的,而且当复制构造函数在类中定义时,



它是直接优化的副本,而不会注意到,如果构造函数是 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); //案例:2
}


解决方案

案例2在N3225中的12.8 / 31下:


如果
copy / move构造函数或副本/ move
对象的赋值运算符是
隐式使用odr,并且不能访问特殊的
成员函数。



b $ b

只是因为复制ctor被省略并不意味着它不是odr使用。 3.2 / 2:


一组候选
函数的成员是odr-如果它是
当通过
潜在求值表达式引用
时,通过重载解析。
[注意:这包括对名为
函数(5.2.2),操作符
重载(第13条),用户定义的
转换(12.3.2)分配
函数用于placement new(5.3.4),作为
以及非默认初始化
(8.5)。复制构造函数或移动
构造函数是odr,即使
调用实际上被
实现省略。 -end note]


请注意,MSVC当然不是完全符合C ++ 0x,因为(a)C ++ 0x不是一个标准,并且没有最终确定;和(b)MSVC还没有实施到目前为止。但这个东西从C ++ 03没有实质性的改变,所以我相当自信的解释仍然成立。



案例1也会来这里,除了在两个C ++ 03编译器,我检查了它不会得到那么远,因为没有可能从一个字符串字面量转换为T.我不能打扰检查是否有任何额外的转换序列允许在C + + 0x,可以在任何地方有一个新的子句: - )



对我来说,为什么MSVC允许case 1,甚至有一个公共副本ctor仍然是一个谜。它是否允许在严格的C ++ 03模式?


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
}

解决方案

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?

这篇关于不为复制初始化或优化调用复制构造函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆