C++ 复制初始化在C+中移动时有效+;11?

C++ 复制初始化在C+中移动时有效+;11?,c++,c++11,copy-constructor,move-semantics,C++,C++11,Copy Constructor,Move Semantics,复制初始化是指在内存中创建Hello,然后使用复制构造函数初始化s,对吗 std::string s = std::string("Hello") 在C++11中引入了移动语义之后,我可以说上面的代码与本例中的代码一样有效(消除了复制): std::string s("Hello"); 编辑:请不要回答字符串字符串只是一个类的示例。我问的不是SSO。我一般都会问 当您使用小于20个字符的字符串(取决于实现)时,短字符串优化就开始了,所有内容都会被复制 但是为了回答您的问题,您的任何示例中都没

复制初始化是指在内存中创建
Hello
,然后使用复制构造函数初始化
s
,对吗

std::string s = std::string("Hello")
在C++11中引入了移动语义之后,我可以说上面的代码与本例中的代码一样有效(消除了复制):

std::string s("Hello");

编辑:请不要回答
字符串
<代码>字符串只是一个类的示例。我问的不是SSO。我一般都会问

当您使用小于20个字符的字符串(取决于实现)时,短字符串优化就开始了,所有内容都会被复制

但是为了回答您的问题,您的任何示例中都没有使用移动语义。在第一种情况下,即使复制构造函数和
string(const char*)
构造函数都必须可用,复制省略也会消除复制

编辑:


为了解决编辑问题,如果您有一个初始化和一个初始化+移动构造函数,那么前者显然总是更快。我之所以提出SSO,是因为人们认为移动操作总是便宜的(甚至是免费的),但不一定,有时甚至根本不会发生。

事实上,C++11之前的情况就是这样,因为


请注意,
std::string
移动并不一定便宜,因为小字符串可能保存在对象本身中,而不是动态分配。这被称为。

简短回答:如果执行复制省略,性能应该相同。否则后者可能会更快


长答覆:

此代码

std::string s = std::string("Hello")
应该在C++11+代码中调用移动构造函数(它需要一个可访问的构造函数)。无论如何,在这种情况下是允许的,尽管不是强制性的(cfr.[class.copy]/p31)

什么时候 如果满足某些条件,则允许实现忽略 复制/移动构造

这些概念已经出现在C++11之前的版本中(它们也适用于复制构造函数)

关于性能问题:

该标准还描述了一些即使复制会改变程序行为也可以消除的情况,最常见的是返回值优化。在C++标准中描述的另一种广泛实现的优化是当类类型的临时对象被复制到同一类型的对象时。(1)结果,复制初始化通常等同于直接初始化,而不是语义上的性能;复制初始化仍然需要可访问的复制构造函数。[2]


如果没有发生复制省略(例如,在gcc中通过
-fno elide构造函数禁用了它,或者出于任何原因编译器不会执行它),那么性能可能会不同,直接初始化应该更快(在本例中,对于
std::string
也可能会影响移动)

当您使用小于20个字符的字符串时(取决于实现),短字符串优化开始,所有内容都被复制。@不需要精确到20个字符。此外,短字符串优化的详细信息和存在性完全取决于实现。@MateuszGrzejek,是的,这就是我编写的原因(取决于实现)如果您不想了解字符串,请将示例中的类名称更改为用户创建的类。@RobK已经很晚了。:)我刚刚发表评论,希望答案也能涵盖一般情况。您的意思是,如果这些不是
std::string
s,那么仍然
a(“Hello”)是首选,对吗?@Narek,是的,在移动发生的情况下,尽管在这种特殊情况下,几乎肯定会发生复制省略。