将正在移动的对象的成员作为参数传递是否安全?

亚历山德罗·佩扎托(Alessandro Pezzato)
#include <iostream>
#include <string>
#include <map>

struct A {
    int n { 42 };
    std::string s { "ciao" };
};

int main() {
    A a;
    std::map<std::string, A> m;
    std::cout << "a.s: " << a.s << std::endl; // print: "a.s: ciao"
    m.emplace(a.s, std::move(a)); // a.s is a member of a, moved in the same line
    std::cout << "in map: " << m.count("ciao") << std::endl; // print: "in map: 1"
    std::cout << "a.s: " << a.s << std::endl; // print: "a.s: " (as expected, it has been moved)
}

将“移动”对象的成员作为参数传递是否安全?在这种情况下,emplace似乎可以工作:地图具有预期的键。

温特穆特

有趣的。出于种种原因,我认为这是安全的。(出于记录的考虑我还认为它的样式非常糟糕-明确的副本在这里不会花您任何钱,因为它将被移至地图中。)

首先,实际的函数调用不是问题。std::move仅强制转换a为右值引用,而右值引用只是引用;a不会立即移动。emplace_back将其参数转发给的构造函数std::pair<std::string, A>,这就是使事情变得有趣的地方。

那么,std::pair使用哪个构造函数它有很多,但是两个是相关的:

pair(const T1& x, const T2& y);
template<class U, class V> pair(U&& x, U&&y);

(请参阅标准中的20.3.2),其中T1T2是的模板参数std::pair根据13.3,我们最终使用U == const T1&V == T2来实现后者,这在直觉上是有意义的(否则std::pair实际上将不可能进入a )。这给我们留下了以下形式的构造函数

pair(const T1& x, T2 &&y) : first(std::forward(x)), second(std::forward(y)) { }

按照20.3.2(6-8)。

那么,这安全吗?有用的std::pair是,定义了一些细节,包括内存布局。它特别指出

T1 first;
T2 second;

按此顺序进入,因此first将在之前初始化second这意味着在您的特定情况下,字符串将在移走之前被复制,因此很安全。

但是,如果您反过来这样做:

m.emplace(std::move(A.s), A); // huh?

...然后您会得到有趣的效果。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

将类的移动成员作为const引用参数传递

来自分类Dev

将_bstr_t对象传递给以BSTR作为参数的函数是否安全?

来自分类Dev

是否可以将匿名对象作为RMI方法的参数传递?

来自分类Dev

C ++将struct成员作为参数传递

来自分类Dev

将 C# 对象(包含静态对象成员)作为参数传递给 C++/CLI 程序

来自分类Dev

是否可以安全地将移动的对象存储在成员引用中?

来自分类Dev

将属性作为指针形式的参数传递给方法是否安全?

来自分类Dev

将LARGE_INTEGER.QuadPart作为size_t的out参数传递是否安全?

来自分类Dev

将数据库项的ID作为URL参数传递是否安全?

来自分类Dev

将xml文档作为存储过程的参数传递到SqlServer中是否安全?

来自分类Dev

将LARGE_INTEGER.QuadPart作为size_t的out参数传递是否安全?

来自分类Dev

将视图控制器作为参数传递给AFNetworking请求是否安全?

来自分类Dev

将动态对象的字段作为参数传递

来自分类Dev

将临时对象作为参数传递(C ++)

来自分类Dev

将String对象作为参数传递

来自分类Dev

将动态对象的字段作为参数传递

来自分类Dev

将json对象作为url参数传递

来自分类Dev

如何使用安全参数将“位图”作为参数传递

来自分类Dev

将静态成员函数作为模板参数传递

来自分类Dev

C ++将指向成员的指针作为模板参数传递

来自分类Dev

将类成员函数作为参数传递给全局函数

来自分类Dev

将静态成员函数作为模板参数传递

来自分类Dev

将指针传递给成员函数作为void *函数的参数

来自分类Dev

将PARENT类的成员名称作为模板参数传递

来自分类Dev

检查传递给成员函数的参数是否是对象本身

来自分类Dev

是否可以将变量作为结构成员传递?

来自分类Dev

将对象作为参数传递是否表示关联关系?

来自分类Dev

将非静态成员函数作为参数传递给成员函数

来自分类Dev

将没有参数的查询传递给PreparedStatement是否安全?

Related 相关文章

  1. 1

    将类的移动成员作为const引用参数传递

  2. 2

    将_bstr_t对象传递给以BSTR作为参数的函数是否安全?

  3. 3

    是否可以将匿名对象作为RMI方法的参数传递?

  4. 4

    C ++将struct成员作为参数传递

  5. 5

    将 C# 对象(包含静态对象成员)作为参数传递给 C++/CLI 程序

  6. 6

    是否可以安全地将移动的对象存储在成员引用中?

  7. 7

    将属性作为指针形式的参数传递给方法是否安全?

  8. 8

    将LARGE_INTEGER.QuadPart作为size_t的out参数传递是否安全?

  9. 9

    将数据库项的ID作为URL参数传递是否安全?

  10. 10

    将xml文档作为存储过程的参数传递到SqlServer中是否安全?

  11. 11

    将LARGE_INTEGER.QuadPart作为size_t的out参数传递是否安全?

  12. 12

    将视图控制器作为参数传递给AFNetworking请求是否安全?

  13. 13

    将动态对象的字段作为参数传递

  14. 14

    将临时对象作为参数传递(C ++)

  15. 15

    将String对象作为参数传递

  16. 16

    将动态对象的字段作为参数传递

  17. 17

    将json对象作为url参数传递

  18. 18

    如何使用安全参数将“位图”作为参数传递

  19. 19

    将静态成员函数作为模板参数传递

  20. 20

    C ++将指向成员的指针作为模板参数传递

  21. 21

    将类成员函数作为参数传递给全局函数

  22. 22

    将静态成员函数作为模板参数传递

  23. 23

    将指针传递给成员函数作为void *函数的参数

  24. 24

    将PARENT类的成员名称作为模板参数传递

  25. 25

    检查传递给成员函数的参数是否是对象本身

  26. 26

    是否可以将变量作为结构成员传递?

  27. 27

    将对象作为参数传递是否表示关联关系?

  28. 28

    将非静态成员函数作为参数传递给成员函数

  29. 29

    将没有参数的查询传递给PreparedStatement是否安全?

热门标签

归档