复制初始化对 C++11 中的 move 有效吗?
Copy initialization is effective with move in C++11?
复制初始化是在内存中创建Hello
,然后使用复制构造函数初始化s
,对吧?
std::string s = std::string("Hello")
在引入移动语义的 C++11 之后,我可以说上面的代码与这种情况一样有效(消除复制):
std::string s("Hello");
编辑:请不要回答 string
。 string
只是 class 的例子。 SSO 是不是这样我问的是什么。我问的一般。
当您使用小于 20 个字符的字符串(取决于实现)时,短字符串优化就会启动,无论如何都会复制所有内容。
但是为了回答您的问题,您的任何示例中都没有使用移动语义。在第一种情况下,即使复制构造函数和 string(const char*)
构造函数都必须可用,复制省略也会消除复制。
编辑:
为了解决您的编辑问题,如果您有一个初始化和一个初始化 + 移动构造函数,那么前者显然总是更快。我提出 SSO 的原因是因为人们认为移动操作总是很便宜(甚至免费),但不一定,有时甚至根本不会发生。
实际上,C++11 之前就是这种情况,因为 copy elision。
请注意,std::string
移动起来不一定便宜,因为小字符串可能保存在对象本身中,而不是动态分配。这被称为 small string optimisation。
简短回答:如果执行复制省略,性能应该相同。否则后者应该会更快。
长答案:
这个代码
std::string s = std::string("Hello")
应该在 C++11+ 代码中调用一个移动构造函数(它需要一个可访问的)。无论如何,在这种情况下 copy elision 是允许的,尽管没有强制要求(参见 [class.copy]/p31)
When
certain criteria are met, an implementation is allowed to omit the
copy/move construction
这些概念在 C++11 之前的版本中已经存在(它们也适用于复制构造函数)。
关于表演问题:
The standard also describes a few situations where copying can be eliminated even if this would alter the program's behavior, the most common being the return value optimization. Another widely implemented optimization, described in the C++ standard, is when a temporary object of class type is copied to an object of the same type.[1] As a result, copy-initialization is usually equivalent to direct-initialization in terms of performance, but not in semantics; copy-initialization still requires an accessible copy constructor.[2]
如果复制省略没有发生(例如,它已通过 -fno-elide-constructors
在 gcc 中被禁用,或者出于任何原因编译器不会执行它)那么性能可能 不会 是相同的,直接初始化应该更快(在这种情况下,std::string
SSO 也可能对移动造成影响)
复制初始化是在内存中创建Hello
,然后使用复制构造函数初始化s
,对吧?
std::string s = std::string("Hello")
在引入移动语义的 C++11 之后,我可以说上面的代码与这种情况一样有效(消除复制):
std::string s("Hello");
编辑:请不要回答 string
。 string
只是 class 的例子。 SSO 是不是这样我问的是什么。我问的一般。
当您使用小于 20 个字符的字符串(取决于实现)时,短字符串优化就会启动,无论如何都会复制所有内容。
但是为了回答您的问题,您的任何示例中都没有使用移动语义。在第一种情况下,即使复制构造函数和 string(const char*)
构造函数都必须可用,复制省略也会消除复制。
编辑:
为了解决您的编辑问题,如果您有一个初始化和一个初始化 + 移动构造函数,那么前者显然总是更快。我提出 SSO 的原因是因为人们认为移动操作总是很便宜(甚至免费),但不一定,有时甚至根本不会发生。
实际上,C++11 之前就是这种情况,因为 copy elision。
请注意,std::string
移动起来不一定便宜,因为小字符串可能保存在对象本身中,而不是动态分配。这被称为 small string optimisation。
简短回答:如果执行复制省略,性能应该相同。否则后者应该会更快。
长答案:
这个代码
std::string s = std::string("Hello")
应该在 C++11+ 代码中调用一个移动构造函数(它需要一个可访问的)。无论如何,在这种情况下 copy elision 是允许的,尽管没有强制要求(参见 [class.copy]/p31)
When certain criteria are met, an implementation is allowed to omit the copy/move construction
这些概念在 C++11 之前的版本中已经存在(它们也适用于复制构造函数)。
关于表演问题:
The standard also describes a few situations where copying can be eliminated even if this would alter the program's behavior, the most common being the return value optimization. Another widely implemented optimization, described in the C++ standard, is when a temporary object of class type is copied to an object of the same type.[1] As a result, copy-initialization is usually equivalent to direct-initialization in terms of performance, but not in semantics; copy-initialization still requires an accessible copy constructor.[2]
如果复制省略没有发生(例如,它已通过 -fno-elide-constructors
在 gcc 中被禁用,或者出于任何原因编译器不会执行它)那么性能可能 不会 是相同的,直接初始化应该更快(在这种情况下,std::string
SSO 也可能对移动造成影响)