【问题标题】:User-provided constructor vs explicitly defaulted one用户提供的构造函数与显式默认的构造函数
【发布时间】:2015-02-17 13:48:15
【问题描述】:

N4296::12.8/11 [class.copy] 告诉我们以下内容:

类 X 的默认复制/移动构造函数被定义为已删除 (8.4.3) 如果 X 有:

[...]

(11.2) — 可能构造的子对象类型 M(或其数组) 无法复制/移动,因为重载决议(13.3),如 应用于 M 的相应构造函数,导致歧义或 从默认设置中删除或无法访问的功能 构造函数

[...]

所以不清楚为什么是这个程序

struct X
{
};

struct Y
{
    X&& x; 
    Y(Y const&)= default;
};

int main() { }

DEMO

工作正常,但以下内容:

struct X
{
};

struct Y
{
    X&& x; 
    Y(Y const&);
};

Y::Y(Y const&)= default; //error

int main() { }

DEMO

【问题讨论】:

    标签: c++ class constructor


    【解决方案1】:

    [dcl.fct.def.default]/p5,强调我的:

    一个函数是用户提供的如果它是用户声明的而不是 在第一次声明时显式默认或删除。一个 用户提供的显式默认函数(即显式 在第一次声明后默认)被定义在 它是明确默认的; 如果隐式定义了这样的函数 删除后,程序格式错误

    这是有道理的,因为任何使用已删除函数都会导致程序格式错误,但使用用户提供的显式默认函数,可能无法在调用站点诊断此问题:

    // 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的拷贝构造函数存在之外,不知道它的存在;它不知道它是默认的,也无法诊断它实际上已被删除。唯一可以诊断出此类错误的地方是函数显式默认的地方。

    【讨论】:

    • 包含已删除构造函数(在我的情况下是复制构造函数)的程序是否格式错误iff构造函数是 odr-used?
    • @DmitryFucintv 哪个程序?如果引用了已删除的函数,而不是声明它,则该程序是格式错误的。
    • This ,例如。在程序中,复制构造函数是 odr-used,如果我可以这么说的话。我的意思是关于使用已删除构造函数的规则是否与 odr-used 概念有关。例如,如果删除的构造函数是 odr-used,则程序是不正确的或类似的东西。
    • @DmitryFucintv 任何使用都足够了,包括在未计算的操作数中;不需要使用 odr。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多