用户提供的构造函数与显式默认的构造函数
User-provided constructor vs explicitly defaulted one
N4296::12.8/11 [class.copy]
告诉我们以下内容:
A defaulted copy/move constructor for a class X is defined as deleted
(8.4.3) if X has:
[...]
(11.2) — a potentially constructed subobject type M (or array thereof)
that cannot be copied/moved because overload resolution (13.3), as
applied to M’s corresponding constructor, results in an ambiguity or a
function that is deleted or inaccessible from the defaulted
constructor
[...]
所以不清楚为什么这个程序
struct X
{
};
struct Y
{
X&& x;
Y(Y const&)= default;
};
int main() { }
工作正常,但以下内容:
struct X
{
};
struct Y
{
X&& x;
Y(Y const&);
};
Y::Y(Y const&)= default; //error
int main() { }
[dcl.fct.def.default]/p5,强调我的:
A function is user-provided if it is user-declared and not
explicitly defaulted or deleted on its first declaration. A
user-provided explicitly-defaulted function (i.e., explicitly
defaulted after its first declaration) is defined at the point where
it is explicitly defaulted; if such a function is implicitly defined
as deleted, the program is ill-formed.
这是有道理的,因为对已删除函数的任何使用都会导致程序格式错误,但是对于用户提供的显式默认函数,可能无法在调用站点进行诊断:
// y.h
struct X
{
};
struct Y
{
X&& x;
Y(Y const&);
};
// y.cpp
#include "y.h"
Y::Y(Y const&)= default; //defined as deleted
// main.cpp
#include "y.h"
int main() {
Y y = Y();
}
编译main.cpp
时,编译器不知道Y
的复制构造函数存在;它不知道它是默认的,并且不可能诊断它实际上被删除了。唯一可以诊断出此类错误的地方是明确默认函数的地方。
N4296::12.8/11 [class.copy]
告诉我们以下内容:
A defaulted copy/move constructor for a class X is defined as deleted (8.4.3) if X has:
[...]
(11.2) — a potentially constructed subobject type M (or array thereof) that cannot be copied/moved because overload resolution (13.3), as applied to M’s corresponding constructor, results in an ambiguity or a function that is deleted or inaccessible from the defaulted constructor
[...]
所以不清楚为什么这个程序
struct X
{
};
struct Y
{
X&& x;
Y(Y const&)= default;
};
int main() { }
工作正常,但以下内容:
struct X
{
};
struct Y
{
X&& x;
Y(Y const&);
};
Y::Y(Y const&)= default; //error
int main() { }
[dcl.fct.def.default]/p5,强调我的:
A function is user-provided if it is user-declared and not explicitly defaulted or deleted on its first declaration. A user-provided explicitly-defaulted function (i.e., explicitly defaulted after its first declaration) is defined at the point where it is explicitly defaulted; if such a function is implicitly defined as deleted, the program is ill-formed.
这是有道理的,因为对已删除函数的任何使用都会导致程序格式错误,但是对于用户提供的显式默认函数,可能无法在调用站点进行诊断:
// y.h
struct X
{
};
struct Y
{
X&& x;
Y(Y const&);
};
// y.cpp
#include "y.h"
Y::Y(Y const&)= default; //defined as deleted
// main.cpp
#include "y.h"
int main() {
Y y = Y();
}
编译main.cpp
时,编译器不知道Y
的复制构造函数存在;它不知道它是默认的,并且不可能诊断它实际上被删除了。唯一可以诊断出此类错误的地方是明确默认函数的地方。