首页 文章

为什么不可能实例化与“非const”复制构造函数的对,而可以实例化一个没有?

提问于
浏览
8

假设您有以下课程:

struct A {
    A () {}
    A (A &) = delete;
};

int main() {
    std::pair<A, int> p1;
    return 0;
}

以下代码将无法编译(使用带有 g++-std=c++11 ),并出现以下错误:

/ usr / include / c /5/bits/stl_pair.h:在'struct std :: pair'的实例化中:test.cpp:13:23:从这里需要/ usr / include / c / 5 / bits / stl_pair .h:127:17:错误:'constexpr std :: pair <_T1,_T2> :: pair(const std :: pair <_T1,_T2>&)[与_T1 = A; _T2 = int]'声明采用const引用,但隐式声明将采用非const constexpr对(const pair&)= default;

根据错误消息,我认为这是因为由于 std::pair 参数上的 const 限定符,无法实现默认的复制构造函数 .

我能理解为什么在没有 = delete 的情况下不能编译,因为不可能实现带有 std::pair const& 参数的复制构造函数 .

但是对于 = delete ,我希望编译器不会实例化这样的构造函数,因为它不能(据我所知) . 实际上,这个拷贝构造函数被删除,如下面这段代码所示:

std::pair<A, int> p1;
decltype(p1) p2(p1);

失败了:

test.cpp:11:23:错误:使用已删除的函数'constexpr std :: pair <_T1,_T2> :: pair(const std :: pair <_T1,_T2>&)[与_T1 = A; _T2 = int]'decltype(p1)p2(p1);

基本上,我的问题是:为什么编译器无法实例化 std::pair 的已删除的复制构造函数?

2 回答

  • 8

    [class.copy]/8

    类X的隐式声明的复制构造函数将具有X :: X(const X&)的形式
    如果每个可能构造的类类型M(或其数组)的子对象具有复制构造函数,其第一个参数的类型为const M&或const volatile M& . 否则,隐式声明的复制构造函数将具有X :: X(X&)形式

    因此,如果要隐式声明 std::pair<A, int> 的复制构造函数,则其形式为 pair::pair(pair &) .

    [dcl.fct.def.default]/1

    显式默认的函数应该是一个特殊的成员函数,具有相同的声明函数类型(可能不同的ref限定符除外,在复制构造函数或复制赋值运算符的情况下,参数类型可能是“引用”) to non const T“,其中T是成员函数类的名称),好像它已被隐式声明,并且没有默认参数 .

    由于声明 pair(const pair&) = default; 与已隐式声明的复制构造函数没有相同的声明函数类型,并且两个都不适用,因此程序格式错误 .

  • 8

    如果你想 = delete 复制构造函数,正确的形式是: A(const A&) = delete; . 看你怎么忘了 constpair 可以与不可复制的类型一起使用,甚至是不可移动的类型 .

    您的实例化问题也可以通过以下方式证明:

    struct A {
        A(A&) = delete;
    };
    
    struct B : A {
        B(const B&) = default;
    };
    

    要么...

    struct B {
        B(const B&) = default;
        A a;
    };
    

    基本上,它的副本ctor,并将其定义为 const pair& ,但是你的一个类型将它定义为采用非const&,因此默认生成失败,因为它可以't pass it'的const和非const& . 虽然你的版本是 = delete ,但它并没有达到目标 .

    如果成员或基类不可复制,则有效删除默认复制文件 . 但为了弄明白这一点,它必须有一个能够调用的函数(即使该函数被删除) . 在这些情况下,它不能传递const&到非const&所以它甚至无法弄清楚你有一个删除的副本ctor . 可以想象,可以编写标准中的某些内容以适应这种边缘情况 .

相关问题