gpt4 book ai didi

c++ - 为什么带大括号的复制初始化会省略复制/移动构造?

转载 作者:行者123 更新时间:2023-12-01 14:04:24 27 4
gpt4 key购买 nike

这个问题在这里已经有了答案:





Does copy list initialization invoke copy ctor conceptually?

(1 个回答)


去年关闭。




这是一个用于比较的 C++ 14 程序 direct initialisation (没有 =)与 copy initialisation ( = ):*

#include <iostream>


struct A {
A(int) { std::cout << "A(int)" << std::endl; }
A(A&) { std::cout << "A(A&)" << std::endl; }
A(A&&) { std::cout << "A(A&&)" << std::endl; }
};


int main() {
A a(1); // direct initialisation
A b{1}; // direct initialisation
A c = 1; // copy initialisation
A d = (1); // copy initialisation
A e = {1}; // copy initialisation
}
使用 copy elision 编译程序禁用并运行它:
$ clang++ -std=c++14 -fno-elide-constructors main.cpp && ./a.out
产生以下输出:
A(int)
A(int)
A(int)
A(A&&)
A(int)
A(A&&)
A(int)
为什么用大括号( A e = {1}; )复制初始化会省略复制/移动构造(即使禁用复制省略)?

* 这种比较背后的动机是为了了解自 C++ 11 以来函数返回语句 ( return expression) 的工作原理。当按值返回时,可以使用函数返回值的直接初始化或复制初始化。后者比像这里这样的变量的复制初始化更复杂,因为从 expression 表示的对象初始化函数返回值。涉及 trying to call the move constructor of the function return type first (即使 expression 是左值)在回退到其复制构造函数之前。并且从 C++ 17 开始,如果 expression,则保证会省略该复制/移动构造。是一个纯右值(强制 return value optimisation),而如果 expression 可能会被省略是一个泛左值(可选 named return value optimisation )。

最佳答案

copy initialisation with braces



哪有这回事。如果您使用花括号初始化列表来初始化一个对象,您正在执行某种形式的列表初始化。这有两种形式:复制列表初始化和直接列表初始化。在 C++14 中,这些与复制初始化和直接初始化无关(从技术上讲,直接列表初始化是 grammatical form of direct-initialization,但由于 list-initialization bypasses everything that direct-initialization would have done,更容易说直接列表初始化是它的自己的野兽)。

列表初始化作为一个概念初始化一个对象。使用 Typename t{}是直接列表初始化,而 Typename t = {}是复制列表初始化。但无论涉及哪种形式,都不会创建临时;列表初始化初始化有问题的对象。您的示例中唯一的对象是 e ,所以这是被初始化的对象。

符合 C++14 rules for list-initialization , ecalling a constructor 初始化,传递一个值 1 ,这是花括号初始化列表中的唯一值。

关于c++ - 为什么带大括号的复制初始化会省略复制/移动构造?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61330444/

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