gpt4 book ai didi

c++ - 复制初始化和直接初始化的混淆

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:22:04 25 4
gpt4 key购买 nike

考虑简单的语句(取自 Is there a difference in C++ between copy initialization and direct initialization? ):

A c2 = A();

This statement value-initializes a temporary and then copies that value into c2 (Read 5.2.3/2 and 8.5/14). This of course will require a non-explicit copy constructor (Read 8.5/14 and 12.3.1/3 and 13.3.1.3/1)

[注意上面段落中的粗体句子] -> 我的问题是为什么?

现在考虑这段代码:

class B {};
struct A
{
A(B const&) {}
A(A const&) = delete;
//A(A const&); //delete above statement and uncomment this statement,
//and everything works, even though there in no body of copy constructor Oo
};

A a2 = B(); //error since there is no copy constructor oO

为什么复制初始化需要存在复制构造函数,即使在上面的代码中有时不需要复制构造函数

请再做一件事:

While direct initialization has all constructors available to call, and in addition can do any implicit conversion it needs to match up argument types, copy initialization can just set up one implicit conversion sequence.

[注意下面段落中的粗体]

那不就意味着直接初始化可以访问所有构造函数,可以执行隐式转换序列,而复制初始化只能执行隐式转换序列吗? .我想问的是,直接初始化中的隐式转换和复制初始化中的隐式转换顺序不同?

最佳答案

评价规则

A a1 = B();   // (1) copy-initialization
A a2 = {B()}; // (2) copy-initialization
A a3{B()}; // (3) direct-initialization

来自[dcl.init]/17 :

— If the initializer is a (non-parenthesized) braced-init-list, the object or reference is list-initialized (8.5.4).
— [...]
— If the destination type is a (possibly cv-qualified) class type:

  • 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. [...]
  • 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). [...] 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.

对于a2a3,初始化器都是braced-init-list,所以我们只进行列表初始化。这最终会调用 B const& 构造函数。

对于 a1,第一个子项目符号不适用 - 因为源类型 (B) 与目标类型 (A)。因此,我们进入涉及考虑转换函数的第二个子要点。有一个 (A(B const&)) 所以我们有效地重写了表达式

A a1_new{A{B{}}};

现在通常会省略这个额外的拷贝。但是你明确禁止它,所以代码无法编译。


至于为什么差异化?我不知道。似乎复制初始化应该只是直接初始化的语法糖。大多数情况下,毕竟是……

关于c++ - 复制初始化和直接初始化的混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35962647/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com