c++ - 为什么在不涉及复制时 std::string s = "123" 被视为复制初始化?
问题描述
为什么这种初始化 std::string: 的方式
std::string s = "123";
被认为是复制初始化,而实际上没有任何复制发生?
在上述情况下,编译器将毫无疑问地看到有一个std::string
接受 a 的构造函数,因此这里发生的事情是通过 to 的隐式转换来char const *
构造一个对象。这是一个如此明确的场景。它只是调用构造函数一次,简单明了。如此简单,甚至没有什么可谈论的优化,例如复制省略和移动。std::string
char const *
std::string
std::string(const char *)
现在,问题是,我从来没有对通过隐式转换(即 Class a = 表达式)进行对象初始化有任何困惑,直到我开始遇到文献声明 = 的初始化是“复制初始化”。甚至主要人物 Bjarne Stroustrup 本人也将这种形式的初始化称为“复制初始化”。
在这一点上,我觉得我可能误会了什么。
那么,如果允许隐式转换显然不是这种情况,为什么由 = 进行的初始化被认为是复制初始化?
解决方案
术语复制初始化仅用于以下形式的初始化语法:
T object = other;
此初始化的效果之一是:
如果 T 是类类型,并且 other 的类型的 cv 非限定版本不是 T 或派生自 T,或者如果 T 是非类类型,但 other 的类型是类类型,则用户定义的转换序列检查可以从 other 的类型转换为 T 的类型(或者如果 T 是类类型并且转换函数可用,则转换为从 T 派生的类型),并通过重载决议选择最佳的类型。
所以对于表达式:
std::string s = "123";
带 a的隐式构造函数const char *
用于构造std::string
.
因此,即使其中包含术语复制,复制初始化并不意味着涉及实际的复制,之所以这样称呼它只是因为语法使它看起来像是正在发生复制。
推荐阅读
- shell - 当 shell 脚本中有执行错误时,Jenkins 构建通过
- python - 如何从模块中找到源代码路径
- c# - 服务器 2019 上的 Internet Explorer 11 中的 UIA AddAutomationFocusChangedEventHandler 内存泄漏
- mysql - 如何遍历 GROUP_CONCAT 列进行比较
- excel - 单元格值未显示
- reactjs - Jest:如何期望 Redux 操作已被调度?
- python - Pytest:如何测试从环境变量设置的类变量?
- c# - 如何在 Microsoft Bot Framework 上执行长任务
- linux-kernel - 使用基于 crosstool-ng 的工具链交叉编译 Linux 内核
- bash - bash脚本不会加载我做错了什么?