调用LLVM中的隐式删除的拷贝构造函数 [英] Call to implicitly deleted copy constructor in LLVM

查看:2449
本文介绍了调用LLVM中的隐式删除的拷贝构造函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据C ++ 11规则,默认生成6个东西(默认构造函数,复制构造函数,移动构造函数,复制赋值,移动赋值和析构函数)。按第二条规则,当定义任何自定义复制,移动或析构函数时,不生成这些默认操作。
但是在我的代码中,后面是不是这样。但是此代码无法编译时出现错误

As per C++11 rules 6 things (default constructor, copy constructor, move constructor, copy assignment, move assignment and destructor ) are generated by default. By second rule, when any custom copy, move or destructor is defined then those default operations are not generated. But in my code that follows that is not the case. But this code fails to compile with an error

调用'Uni'的隐式删除的拷贝构造函数

call to implicitly deleted copy constructor of 'Uni'

我写我自己的复制构造函数为Uni一切工作正常。 (在代码中注释,给出以供参考)

When I write my own copy constructor for Uni everything works fine. (It is commented in the code, given for reference )

任何想法非常感激。

很多谢谢...

#include <iostream>

class A
{
public:
    A(int i) :num{i}
    {
        std::clog<< "ctor  A() num = " << num << "\n";

    }
    A( A const &aRef)
    :num{aRef.num}
    {
        std::clog << " copy ctor A( A const &aRef) num = " << num << "\n";
    }

    int value()
    {
        return num;
    }

private:
    int num;

};
class Uni
{

public:
    Uni(A* aptr) : up{aptr}
    {
        std::clog << " ctor Uni value = " << up.get()->value() << "\n";
    }
    /*Uni(Uni const &uRef)
    {
        std::clog << " copy ctor Uni copying obj pointed by unique_ptr\n";
        up.reset(uRef.up.get() ? new A{*uRef.up.get()} : nullptr);
    }*/
private:
    std::unique_ptr<A> up;

};

int main(int argc, const char * argv[])
{
    Uni one{new A{10}};
    Uni two{one}; //default copy ctor is implicitly deleted. why ?
}


推荐答案

C ++ 11自动生成特殊成员不像你发布它们那么简单。最重要的区别是在某些情况下,成员被隐式声明,但定义为已删除。

C++11 rules for automatic generation of special members aren't as simple as you posted them. The most important distinction is that in some cases, the member is implicitly declared, but defined as deleted. That's what happens in your case.

C ++ 11,[class.copy]§11:

C++11, [class.copy]§11:


X 的默认复制/移动构造函数定义为删除(8.4.3)if X 有:

A defaulted copy/move constructor for a class X is defined as deleted (8.4.3) if X has:


  • 一个具有非平凡对应构造函数和 X 是类似于union的类,

  • 类类型 M 不能被复制/移动,因为应用于 M 的相应构造函数的重载分辨率(13.3)导致模糊或被删除或不可访问的函数默认的构造函数

  • 无法复制/移动的直接或虚拟基类 B )应用于 B 的相应构造函数时,会导致模糊度或函数从默认构造函数中删除或无法访问,

  • 任何具有从默认构造函数中删除或无法访问的析构函数的类型的直接或虚拟基类或非静态数据成员,

  • 用于复制构造函数,非静态右值引用类型的数据成员,或

  • 用于移动构造函数,非静态数据成员或直接或虚拟基类,其类型不具有移动构造函数,可以复制。

  • a variant member with a non-trivial corresponding constructor and X is a union-like class,
  • a non-static data member of class 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,
  • a direct or virtual base class B that cannot be copied/moved because overload resolution (13.3), as applied to B's corresponding constructor, results in an ambiguity or a function that is deleted or inaccessible from the defaulted constructor,
  • any direct or virtual base class or non-static data member of a type with a destructor that is deleted or inaccessible from the defaulted constructor,
  • for the copy constructor, a non-static data member of rvalue reference type, or
  • for the move constructor, a non-static data member or direct or virtual base class with a type that does not have a move constructor and is not trivially copyable.

(强调我)

更一般地说,自动生成类成员的规则是:

More generally, the rules for auto-generated class members are:


  • 如果类没有用户提供的构造函数,则声明一个默认构造函数。

  • If the class has no user-provided constructors, a default constructor is declared.

如果类没有{用户提供的复制或移动构造函数,用户提供的副本或移动赋值运算符,用户提供的析构函数}

If the class has none of { user-provided copy or move constructor, user-provided copy or move assignment operator, user-provided destructor }, a move constructor will be declared (but see (*) below).

如果类没有用户提供的副本赋值操作符,那么将会声明一个移动构造函数

If the class doesn't have a user-provided copy assignment operator, one is declared.

如果类没有{用户提供的复制或移动构造函数,用户提供的副本或移动赋值运算符,用户提供的析构函数}

If the class has none of { user-provided copy or move constructor, user-provided copy or move assignment operator, user-provided destructor }, a move assignment operator will be declared (but see (*) below).

如果类没有用户提供的析构函数,那么将会声明一个移动赋值操作符

If the class doesn't have a user-provided destructor, one is declared.

任何自动声明的成员都可以定义为默认成员(做默认东西)或定义为已删除你试图使用它,你会得到一个错误)。经验法则是如果默认版本有意义,它将被定义为默认值,否则将被定义为已删除。

Any automatically declared member can be defined as defaulted (doing the default stuff) or defined as deleted (if you try to use it, you get an error). The rule of thumb is "If the defaulted version makes sense, it will be defined as defaulted. Otherwise, it will be defined as deleted."

有意义意味着不试图调用一个删除,模糊,不可访问或其他非法的函数。例如,在本回答的第一部分中引用的标准位列出了对于复制构造函数没有有意义的内容。

In this context, "makes sense" means "doesn't try to call a deleted, ambiguous, inaccessible or otherwise illegal function." For example, the standard bit I quoted in the first part of this answer lists what doesn't "make sense" for copy constructors.

此外,自动声明的复制构造函数

Additionally, an automatically declared copy constructor or copy assignment operator is defined as deleted if the class has a user-provided move constructor or move assignment operator.

(*)如果一个自动声明的移动构造函数或移动赋值操作符被定义为已删除运算符将被定义为已删除,而不是完全未声明。这条规则存在,所以试图移动这样的类隐式地落回到复制它而不是生成错误。

(*) If an automatically declared move constructor or move assignment operator would be defined as deleted, it is instead not declared at all. This rule exists so that trying to move such a class implicitly falls back to copying it instead of generating an error.

这篇关于调用LLVM中的隐式删除的拷贝构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆