C ++移动构造函数未调用右值引用 [英] C++ move constructor not called for rvalue reference

查看:96
本文介绍了C ++移动构造函数未调用右值引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

class MyClass {
  public:
      MyClass()
      {
          std::cout << "default constructor\n";
      }
      MyClass(MyClass& a)
      {
          std::cout << "copy constructor\n";
      }

      MyClass(MyClass&& b)
      {
          std::cout << "move constructor\n";
      } 
};  

void test(MyClass&& temp)
{
    MyClass a(MyClass{}); // calls MOVE constructor as expected
    MyClass b(temp); // calls COPY constructor... not expected...? 
}

int main()
{
    test(MyClass{});
    return 0;
}

对于上面的代码,我希望在test()中创建的两个对象都可以调用move构造函数,因为b是r值引用类型(MyClass&&).

For the above code, I expected both object creations in test() to call move constructor because b is a r-value reference type (MyClass&&).

但是,将b传递给MyClasss构造函数不会像预期的那样调用move构造函数,而是调用copy构造函数.

However, passing b to the MyClasss constructor does not call move constructor as expected, but calls copy constructor instead.

即使传递的参数的类型为MyClass&& ;,为什么第二种情况也调用复制构造函数(r值参考)???

Why does second case calls copy constructor even if the passed argument is of type MyClass&& (r-value reference)???

我正在使用gcc 5.2.1.要重现我的结果,必须将-fno-elide-constructors选项传递给gcc以禁用复制删除优化.

I am using gcc 5.2.1. To reproduce my results, you must pass -fno-elide-constructors option to gcc to disable copy elision optimization.

void test(MyClass&& temp)
{
    if (std::is_rvalue_reference<decltype(temp)>::value)
        std::cout << "temp is rvalue reference!!\n";
    else
       std::cout << "temp is NOT rvalue!!\n";
}

即使命名为temp,以上代码也会打印出"temp is rvalue reference".

Above code prints out "temp is rvalue reference" even if temp is named.

temp的类型是右值引用类型.

temp's type is rvalue reference type.

推荐答案

void test(MyClass&& temp)
{
    MyClass a(MyClass{}); // calls MOVE constructor as expected
    MyClass b(temp); // calls COPY constructor... not expected...? 
}

这是因为temp(因为它具有名称)是对rvaluelvalue引用.要随时将其视为rvalue,请调用std::move

That is because, temp (since it has a name,) is an lvalue reference to an rvalue. To treat as an rvalue at any point, call on std::move

void test(MyClass&& temp)
{
    MyClass a(MyClass{}); // calls MOVE constructor as expected
    MyClass b(std::move(temp)); // calls MOVE constructor... :-) 
}

这篇关于C ++移动构造函数未调用右值引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆