如果复制构造函数为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
}
答案 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");
吗?
它是否直接优化了副本而没有注意到构造函数是否为私有?
不,不能。编译器通常在代码优化阶段之前执行语法和语义分析。