【问题标题】:Why does the compiler choose the copy ctor after calling move为什么编译器在调用move后会选择copy ctor
【发布时间】:2018-03-08 17:36:45
【问题描述】:


对于下面的代码,我知道因为我实现了一个复制构造函数默认移动被编译器阻止,我不明白的是为什么编译器选择复制构造函数,而不是发出错误?
如果不存在右值引用函数,右值引用可以作为引用函数的参数吗?
如果没有,这里会发生什么?

#include <iostream>

using namespace std;

class A{
    public:

        A(){printf("constructor\n");}
        A(const A& a){printf("copy constructor");}
};

int main()
{ 
    A a;
    A b = std::move(a);
    return 1; 
}

输出是:

constructor
copy constructor

谢谢

【问题讨论】:

  • "如果不存在右值 ref 函数,是否可以将 ravlue 引用作为引用函数的参数?" -- 可以。
  • 可以肯定的是,ravlue 引用可以作为左值引用函数参数的参数吗?谢谢!
  • @DsCpp 不完全是。可以传递给const &amp; 参数。相关/欺骗:stackoverflow.com/questions/36102728/…
  • 您可以在自己的示例中清楚地看到它可以。

标签: c++ copy-constructor rvalue-reference move-constructor


【解决方案1】:

原因是右值表达式可以绑定到const左值引用的函数参数。


还要注意const 右值表达式不能绑定到右值引用:

class A{
    public:    
        A(){printf("constructor\n");}
        A(const A& a){printf("copy constructor");}
        A(A&&) = default; // <-- has move ctor
}; 

int main()
{ 
    const A a; // <-- const!
    A b = std::move(a); // <-- copy not move!!!
    return 1; 
}

上面的代码仍然调用复制构造函数,即使有一个移动构造函数。

【讨论】:

  • 这是对问题的一个很好的补充,谢谢
【解决方案2】:

std::move 将获取您的命名值并将其转换为右值表达式,仅此而已。

并且,就像任何其他右值一样,如果它不能移动,它将被复制。

T 类型的右值可以绑定到 const T&amp; 就好了。

【讨论】:

    猜你喜欢
    • 2019-04-24
    • 2019-11-09
    • 2013-08-18
    • 1970-01-01
    • 1970-01-01
    • 2022-11-02
    • 1970-01-01
    • 2021-08-09
    • 2015-04-20
    相关资源
    最近更新 更多