首页 > 解决方案 > 为什么在不涉及复制时 std::string s = "123" 被视为复制初始化?

问题描述

为什么这种初始化 std::string: 的方式 std::string s = "123"; 被认为是复制初始化,而实际上没有任何复制发生?

在上述情况下,编译器将毫无疑问地看到有一个std::string接受 a 的构造函数,因此这里发生的事情是通过 to 的隐式转换来char const *构造一个对象。这是一个如此明确的场景。它只是调用构造函数一次,简单明了。如此简单,甚至没有什么可谈论的优化,例如复制省略和移动。std::stringchar const *std::stringstd::string(const char *)

现在,问题是,我从来没有对通过隐式转换(即 Class a = 表达式)进行对象初始化有任何困惑,直到我开始遇到文献声明 = 的初始化是“复制初始化”。甚至主要人物 Bjarne Stroustrup 本人也将这种形式的初始化称为“复制初始化”。

在这一点上,我觉得我可能误会了什么。

那么,如果允许隐式转换显然不是这种情况,为什么由 = 进行的初始化被认为是复制初始化?

标签: c++

解决方案


术语复制初始化仅用于以下形式的初始化语法:

T object = other;

此初始化的效果之一是:

如果 T 是类类型,并且 other 的类型的 cv 非限定版本不是 T 或派生自 T,或者如果 T 是非类类型,但 other 的类型是类类型,则用户定义的转换序列检查可以从 other 的类型转换为 T 的类型(或者如果 T 是类类型并且转换函数可用,则转换为从 T 派生的类型),并通过重载决议选择最佳的类型。

所以对于表达式:

std::string s = "123"; 

带 a的隐式构造函数const char *用于构造std::string.

因此,即使其中包含术语复制,复制初始化并不意味着涉及实际的复制,之所以这样称呼它只是因为语法使它看起来像是正在发生复制。


推荐阅读