在复制初始化时,是调用复制构造函数显式还是隐式? [英] In copy-initialization, is the call to the copy constructor explicit or implicit?

查看:124
本文介绍了在复制初始化时,是调用复制构造函数显式还是隐式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

class AAA {
public:
    explicit AAA(const AAA&) {}
    AAA(int) {}
};


int main() {
    AAA a = 1;
    return 0;
}



在上面的代码中,如我所知,尽管在大多数情况下拷贝构造函数在语义上仍然需要被调用。我的问题是,是调用显式还是隐式?很长一段时间,我得到的结论是,对 AAA :: AAA(int)的调用是隐式的,但是对复制构造函数的调用不是。今天我不小心得到g ++编译上面的代码,它报告错误。 (VC12编译成功。)

In the above code, as I understand, though elided in most cases, the copy constructor is still semantically required to be called. My question is, is the call explicit or implicit? For a long time I have the conclusion in my mind that the call to AAA::AAA(int) is implicit but the call to the copy constructor is not. Today I accidentally got g++ to compile the above code and it reported error. (VC12 compiles OK.)

在标准的第8.5节:


如果目标类型是(可能是cv限定的)类类型:

If the destination type is a (possibly cv-qualified) class type:


  • 如果初始化是直接初始化,它是复制初始化,其中源
    类型的cv非限定版本是与
    目的地的类相同的类或者派生类,构造函数被考虑。适用的构造函数
    被枚举(13.3.1.3),最好的构造函数通过重载
    分辨率(13.3)来选择。调用这样选择的构造函数来初始化
    对象,初始化表达式或表达式列表作为其
    参数。如果没有构造函数应用,或者重载解析是
    模糊,则初始化是错误的。

  • If the initialization is direct-initialization, or if it is copy-initialization where the cv-unqualified version of the source type is the same class as, or a derived class of, the class of the destination, constructors are considered. The applicable constructors are enumerated (13.3.1.3), and the best one is chosen through overload resolution (13.3). The constructor so selected is called to initialize the object, with the initializer expression or expression-list as its argument(s). If no constructor applies, or the overload resolution is ambiguous, the initialization is ill-formed.

否则(即,初始化情况),可以从源
类型转换为目标类型或(当使用转换函数时)
到其派生类的用户定义转换序列,如第13.3.1.4节所述,
和最好的一个通过重载分辨率(13.3)选择。如果
转换不能完成或不明确,初始化是
不成形。所选的函数以初始化器
表达式作为其参数来调用;如果函数是一个构造函数,调用
初始化
目标类型的cv非限定版本的临时。临时是一个贬值。然后根据上面的规则,调用
(它是构造函数的临时变量)的结果用于
direct-initialize ,对象是
复制初始化的目的地。在某些情况下,允许
实现通过直接将中间结果
构造到正被初始化的对象中来消除该
直接初始化中固有的复制;请参阅12.2,12.8。

Otherwise (i.e., for the remaining copy-initialization cases), user-defined conversion sequences that can convert from the source type to the destination type or (when a conversion function is used) to a derived class thereof are enumerated as described in 13.3.1.4, and the best one is chosen through overload resolution (13.3). If the conversion cannot be done or is ambiguous, the initialization is ill-formed. The function selected is called with the initializer expression as its argument; if the function is a constructor, the call initializes a temporary of the cv-unqualified version of the destination type. The temporary is a prvalue. The result of the call (which is the temporary for the constructor case) is then used to direct-initialize, according to the rules above, the object that is the destination of the copy-initialization. In certain cases, an implementation is permitted to eliminate the copying inherent in this direct-initialization by constructing the intermediate result directly into the object being initialized; see 12.2, 12.8.



<初始化在上面的引号意味着对复制构造函数的调用是显式的,对吧?是g ++错误还是我对标准的解释错了?

The bolded direct-initialize in the above quotes means the call to copy constructor is explicit, right? Is g++ wrong or my interpretation of the standard wrong?

推荐答案

看起来像这个错误: g ++无法在复制初始化的第二步调用显式构造函数


g ++无法编译以下代码

g++ fails to compile the following code

struct X
{
    X(int) {}
    explicit X(X const &) {}
};

int main()
{
    X x = 1; // error: no matching function for call to 'X::X(X)'
}

复制初始化的第二步(见8.5 / 16/6/2)是一个
直接初始化,其中显式构造函数被认为是
作为候选函数。

The second step of a copy initialization (see 8.5/16/6/2) is a direct-initialization where explicit constructors shall be considered as candidate functions.

这篇关于在复制初始化时,是调用复制构造函数显式还是隐式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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