1

如果创建了复制构造函数,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
}
4

2 回答 2

5

案例 2 在 N3225 中低于 12.8/31:

如果对象的复制/移动构造函数或复制/移动赋值运算符被隐式使用并且特殊成员函数不可访问,则程序是不正确的。

仅仅因为复制 ctor 被省略并不意味着它没有被 ODR 使用。3.2/2:

如果在从潜在评估的表达式中引用时,通过重载决议选择了一组候选函数的成员,则该成员是 odr-used 的。[注意:这包括对命名函数的调用(5.2.2)、运算符重载(第 13 条)、用户定义的转换(12.3.2)、用于放置 new 的分配函数(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 模式下使用?

于 2011-01-09T14:57:48.510 回答
2

情况1:没有错误,编译器不在乎复制构造函数是否在类中定义。

T a = ("Copy Initialization"); 应该给出一个错误,因为没有合适的构造函数可以转换"const char [20]""T"

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

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

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

于 2011-01-09T14:16:42.570 回答