复制构造函数不会被调用进行复制初始化或优化?

时间:2011-01-09 14:07:06

标签: c++ visual-c++-2010

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

案例1:没有错误,编译器不关心是否在类中定义了复制构造函数。

案例2:错误,复制构造函数是私有的,当它被创建public时,它就被删除了。

它是否直接优化了副本而没有注意到构造函数是否为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
}

2 个答案:

答案 0 :(得分:5)

案例2在N3225中为12.8 / 31:

  

如果一个程序是不正确的   复制/移动构造函数或复制/移动   对象的赋值运算符是   隐含的使用和特殊的   成员函数无法访问。

仅仅因为复制文件被删除并不意味着它没有使用。 3.2 / 2:

  

一组候选人的成员   如果是的话,函数会被使用   由重载决议选择时   提到的   潜在评估的表达。   [注意:这包括对命名的调用   功能(5.2.2),操作员   超载(第13条),用户定义   转换(12.3.2),分配   放置新功能(5.3.4),如   以及非默认初始化   (8.5)。复制构造函数或移动   构造函数即使是使用也是有用的   电话实际上已经被删除了   实现。 - 后注]

当然要注意MSVC 完全符合C ++ 0x,因为(a)C ++ 0x尚未成为标准,并且尚未最终确定; (b)MSVC无论如何都没有实现最新的一切。但是这个东西并没有从C ++ 03中发生实质性的改变,所以我相信这个解释仍然存在。

案例1也属于这种情况,除了在两个C ++ 03编译器上我已经检查过它没有那么远,因为没有可能从字符串文字转换为T.我不能被打扰要检查C ++ 0x中是否允许有任何其他转换序列,可能在任何地方都有新的子句: - )

对我来说,为什么MSVC允许案例1,即使是公共副本ctor,这仍然是个谜。它是否允许在严格的C ++ 03模式下使用?

答案 1 :(得分:2)

  

案例1:没有错误,编译器不关心是否在类中定义了复制构造函数。

T a = ("Copy Initialization"); should give an error因为没有合适的构造函数可以从"const char [20]"转换为"T"

您的意思是T a = std::string("Copy Initialization");吗?

  

它是否直接优化了副本而没有注意到构造函数是否为私有?

不,不能。编译器通常在代码优化阶段之前执行语法和语义分析。