c++ - 与 move 构造函数混淆 : unable to call move constructor

标签 c++ move-semantics rvalue-reference move-constructor most-vexing-parse

我一直难以理解 C++ 中的 move 构造函数。我用默认构造函数、复制构造函数、 move 构造函数和析构函数制作了一个简单的类。此外,我定义了一个具有两个重载的函数,一个接受对该类的引用,一个接受对该类的右值引用。我的测试代码如下。

#include <iostream>


class c {

public:

    c() {
        std::cout << "default constructor" << std::endl;
    }

    c(const c& s) {
        std::cout << "copy constructor" << std::endl;
    }

    c(c&& s) {
        std::cout << "move constructor" << std::endl;
    }

    ~c() {
        std::cout << "destructor" << std::endl;
    }

};

void f(c& s) {
    std::cout << "passed by reference" << std::endl;
}

void f(c&& s) {
    std::cout << "passed by rvalue reference" << std::endl;
}

int main() {

    c s1; // line 1
    std::cout << "\n";
    c s2(s1); // line 2
    std::cout << "\n";
    c s3(c()); // line 3

    std::cout << "\n";

    f(s1); // line 4
    std::cout << "\n";
    f(c()); // line 5

    getchar();
    return 0;

}

我得到的输出不是我所期望的。以下是我从此代码获得的输出。

default constructor

copy constructor

passed by reference

default constructor
passed by rvalue reference
destructor

除了第 3 行,我能理解所有行的输出。在 第 3 行,即 c s3(c());c() 是一个右值,所以我希望 s3 将被 move 构造。但是输出没有显示它是 move 构造的。在 第 5 行 上,我做了同样的事情并将 rvalue 传递给函数 f(),它确实调用了接受的重载右值 引用。我很困惑,如果有任何相关信息,我将不胜感激。

编辑:如果我执行 c s3(std::move(c())); 我可以调用 move 构造函数,但我是否已经通过s3 的右值?为什么我需要 std::move

最佳答案

您看不到第 3 行的任何输出的原因是它声明了一个函数,而不是一个变量。这是由于称为 Most Vexing Parse 的歧义。 .

c s3(c())int foo(int ()) 进行比较,由于隐式类型调整,后者与 int 相同foo(int (*f)()).

要解决这个问题,请使用大括号初始化(实际上在 C++11 中部分出于这个原因引入):

c s3(c{});

// or

c s3{c()};

// or

c s3{c{}};

关于c++ - 与 move 构造函数混淆 : unable to call move constructor,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44331103/

相关文章:

c++ - 为什么使用 `none const copy constructor` 时编译器会报错?

c++ - 为什么 std::optional 不允许对 "move construct and copy assign only"类型进行 move 赋值?

c++ - 使用 std::move,调用 move 构造函数但对象仍然有效

c++ - C/C++ 通用控件检测 TVItem 的双击

c++ - 需要 Webkit 和 C++ 示例代码来从文件中读取和显示 HTML

c++ - SetThreadpoolCallbackPriority 是否适用于 IO 回调

c++ - 为什么auto && var2不隐含右值引用?

c++ - 在 C++ 中使用回调函数抓取帧。它如何与类(class)交流?

c++ - 我是否经常使用 std::move() ?

c++ - 右值引用与 "&& &&"崩溃的示例