- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
根据 C++11 规则,默认生成 6 个东西(默认构造函数、复制构造函数、移动构造函数、复制赋值、移动赋值和析构函数)。根据第二条规则,当定义了任何自定义复制、移动或析构函数时,不会生成这些默认操作。但在我后面的代码中,情况并非如此。但是这段代码编译失败,报错
call to implicitly deleted copy constructor of 'Uni'
当我为 Uni 编写自己的复制构造函数时,一切正常。 (代码中有注释,供引用)
任何想法都非常感谢。
最后,我在 Mac 上运行这个,Xcode 和 LLVM 编译器。
非常感谢...
#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,[class.copy]§11:
A defaulted copy/move constructor for a class
X
is defined as deleted (8.4.3) ifX
has:
- 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 toM
'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 toB
'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.
(强调我的)
更一般地说,自动生成的类成员的规则是:
如果类没有用户提供的构造函数,则声明一个默认构造函数。
如果类没有用户提供的复制构造函数,则声明一个。
如果类没有{用户提供的复制或移动构造函数,用户提供的复制或移动赋值运算符,用户提供的析构函数},则将声明移动构造函数(但请参阅下面的(*)) .
如果类没有用户提供的复制赋值运算符,则声明一个。
如果类没有{用户提供的复制或移动构造函数,用户提供的复制或移动赋值运算符,用户提供的析构函数},则将声明移动赋值运算符(但请参阅下面的(*) )。
如果类没有用户提供的析构函数,则声明一个。
任何自动声明的成员都可以定义为默认(执行默认操作)或定义为已删除(如果您尝试使用它,则会出错)。经验法则是“如果默认版本有意义,则将其定义为默认版本。否则,将其定义为已删除。”
在这种情况下,“有意义”是指“不尝试调用已删除、模棱两可、不可访问或其他非法的函数”。例如,我在这个答案的第一部分引用的标准位列出了对复制构造函数没有“意义”的内容。
此外,如果类具有用户提供的移动构造函数或移动赋值运算符,则将自动声明的复制构造函数或复制赋值运算符定义为已删除。
(*) 如果将自动声明的移动构造函数或移动赋值运算符定义为已删除,则根本不声明它。这条规则的存在使得试图隐式移动这样的类会退回到复制它而不是产生错误。
关于c++ - 调用 LLVM 中隐式删除的复制构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19559503/
C语言sscanf()函数:从字符串中读取指定格式的数据 头文件: ?
最近,我有一个关于工作预评估的问题,即使查询了每个功能的工作原理,我也不知道如何解决。这是一个伪代码。 下面是一个名为foo()的函数,该函数将被传递一个值并返回一个值。如果将以下值传递给foo函数,
CStr 函数 返回表达式,该表达式已被转换为 String 子类型的 Variant。 CStr(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CSng 函数 返回表达式,该表达式已被转换为 Single 子类型的 Variant。 CSng(expression) expression 参数是任意有效的表达式。 说明 通常,可
CreateObject 函数 创建并返回对 Automation 对象的引用。 CreateObject(servername.typename [, location]) 参数 serv
Cos 函数 返回某个角的余弦值。 Cos(number) number 参数可以是任何将某个角表示为弧度的有效数值表达式。 说明 Cos 函数取某个角并返回直角三角形两边的比值。此比值是
CLng 函数 返回表达式,此表达式已被转换为 Long 子类型的 Variant。 CLng(expression) expression 参数是任意有效的表达式。 说明 通常,您可以使
CInt 函数 返回表达式,此表达式已被转换为 Integer 子类型的 Variant。 CInt(expression) expression 参数是任意有效的表达式。 说明 通常,可
Chr 函数 返回与指定的 ANSI 字符代码相对应的字符。 Chr(charcode) charcode 参数是可以标识字符的数字。 说明 从 0 到 31 的数字表示标准的不可打印的
CDbl 函数 返回表达式,此表达式已被转换为 Double 子类型的 Variant。 CDbl(expression) expression 参数是任意有效的表达式。 说明 通常,您可
CDate 函数 返回表达式,此表达式已被转换为 Date 子类型的 Variant。 CDate(date) date 参数是任意有效的日期表达式。 说明 IsDate 函数用于判断 d
CCur 函数 返回表达式,此表达式已被转换为 Currency 子类型的 Variant。 CCur(expression) expression 参数是任意有效的表达式。 说明 通常,
CByte 函数 返回表达式,此表达式已被转换为 Byte 子类型的 Variant。 CByte(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CBool 函数 返回表达式,此表达式已转换为 Boolean 子类型的 Variant。 CBool(expression) expression 是任意有效的表达式。 说明 如果 ex
Atn 函数 返回数值的反正切值。 Atn(number) number 参数可以是任意有效的数值表达式。 说明 Atn 函数计算直角三角形两个边的比值 (number) 并返回对应角的弧
Asc 函数 返回与字符串的第一个字母对应的 ANSI 字符代码。 Asc(string) string 参数是任意有效的字符串表达式。如果 string 参数未包含字符,则将发生运行时错误。
Array 函数 返回包含数组的 Variant。 Array(arglist) arglist 参数是赋给包含在 Variant 中的数组元素的值的列表(用逗号分隔)。如果没有指定此参数,则
Abs 函数 返回数字的绝对值。 Abs(number) number 参数可以是任意有效的数值表达式。如果 number 包含 Null,则返回 Null;如果是未初始化变量,则返回 0。
FormatPercent 函数 返回表达式,此表达式已被格式化为尾随有 % 符号的百分比(乘以 100 )。 FormatPercent(expression[,NumDigitsAfterD
FormatNumber 函数 返回表达式,此表达式已被格式化为数值。 FormatNumber( expression [,NumDigitsAfterDecimal [,Inc
我是一名优秀的程序员,十分优秀!