简体   繁体   English

在复制初始化中,对复制构造函数的调用是显式还是隐式的?

[英]In copy-initialization, is the call to the copy constructor explicit or implicit?

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


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

In the above code, as I understand, though elided in most cases, the copy constructor is still semantically required to be called. 据我所知,在上面的代码中,尽管在大多数情况下都可以省略,但在语义上仍然需要调用copy构造函数。 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. 很长一段时间以来,我的结论是对AAA::AAA(int)的调用是隐式的,但对复制构造函数的调用却不是。 Today I accidentally got g++ to compile the above code and it reported error. 今天,我偶然得到了g ++来编译上述代码,并报告了错误。 (VC12 compiles OK.) (VC12编译正常。)

In section 8.5 of the standard: 在标准的8.5节中:

If the destination type is a (possibly cv-qualified) class type: 如果目标类型是(可能是cv限定的)类类型:

  • 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. 如果初始化是直接初始化,或者如果复制是初始化,其中源类型的cv不合格版本与目标的类相同,或为该类的派生类,则考虑构造函数。 The applicable constructors are enumerated (13.3.1.3), and the best one is chosen through overload resolution (13.3). 列举了适用的构造函数(13.3.1.3),并通过重载分辨率(13.3)选择了最佳的构造函数。 The constructor so selected is called to initialize the object, with the initializer expression or expression-list as its argument(s). 如此选择的构造函数将以初始化器表达式或expression-list作为其自变量来初始化对象。 If no constructor applies, or the overload resolution is ambiguous, the initialization is ill-formed. 如果没有构造函数适用,或者重载解决方案不明确,则初始化格式错误。

  • Otherwise (ie, 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). 否则(即,对于其余的复制初始化情况),将枚举可以从源类型转换为目标类型或(当使用转换功能时)转换为其派生类的用户定义转换序列,如13.3所述。 1.4,最佳选择是通过过载分辨率(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. 如果函数是构造函数,则调用将初始化目标类型的cv不合格版本的临时版本。 The temporary is a prvalue. 临时变量是一个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. 参见12.2、12.8。

The bolded direct-initialize in the above quotes means the call to copy constructor is explicit, right? 以上引号中的粗体direct-initialize表示对复制构造函数的调用是显式的,对吗? Is g++ wrong or my interpretation of the standard wrong? g ++错误还是我对标准的解释错误?

Looks like this bug: g++ fails to call explicit constructors in the second step of copy initialization 看起来像这个错误: g ++在复制初始化的第二步中未能调用显式构造函数

g++ fails to compile the following code g ++无法编译以下代码

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

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. 复制初始化的第二步(请参见8.5 / 16/6/2)是直接初始化,在该直接初始化中,应将显式构造函数视为候选函数。

Looks like copy constructor is never called . 看起来从未调用过复制构造函数。 Only constructor is called . 仅调用构造函数。 The following code may call copy constructor 以下代码可以调用复制构造函数

AAA a = 1;
AAA ab = a;

Not sure why G++ is compiling it . 不知道为什么G ++会编译它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM