c++11 - 无法运行 move 构造函数

标签 c++11 move-semantics curly-braces move-constructor uniform-initialization

C++11

我在使用 move 构造函数时遇到问题。我有一个简单的容器类,名为 Number,其唯一的数据成员是整数。我有以下代码:

//Number.h
#ifndef NUMBER_H
#define NUMBER_H
#include <iostream>

class Number
{
public:
    Number();
    Number(int ipar);
    Number(const Number& src);
    Number(Number&& src);
private:
    int num;
};

#endif

//Number.cpp
#include "Number.h"

Number::Number()
{
    std::cout << "default ctor" << std::endl;
}

Number::Number(int ipar) : num(ipar)
{
    std::cout << "integer argument ctor" << std::endl;
}

Number::Number(const Number& src) : num(src.num)
{
    std::cout << "copy ctor" << std::endl;
}

Number::Number(Number&& src) : num(src.num)
{
    std::cout << "move ctor" << std::endl;
}

//main.cpp
#include "Number.h"
using namespace std;

int main()
{
    cout << "Part A:" << endl;
    Number n1(1);
    cout << "Part B:" << endl;
    Number n2(n1);
    cout << "Part C:" << endl;
    Number n3{Number{n1}};
    cout << "Part D:" << endl;
    Number n4(Number(n1));
    return 0;
}

输出:

Part A:
integer argument ctor
Part B:
copy ctor
Part C:
copy ctor
Part D:

请注意,D 部分没有输出。A 部分和 B 部分的输出符合我的预期,但其他部分的输出并非如此。

我预计 C 和 D 部分会这样:

Part C:
copy ctor
move ctor
Part D:
copy ctor
move ctor

对 C 部分的期望:

我期望 Number n3{Number{n1}}Number{n1} 部分创建一个临时无名 Number 对象,因为通过使用 n1 调用复制构造函数,Number 和左大括号之间没有名称。然后我期望通过使用临时对象调用 move 构造函数来构造 Number n3

对 D 部分的期望:

由于这与 C 部分类似,只是使用圆括号而不是大括号,因此我希望该部分的行为和输出方式与我预期 C 部分相同。

问题:

为什么实际输出与我的期望不同?获得所需输出的正确方法是什么?

注意:如果您想在 Visual Studio 中编译此文件,则需要 Visual C++ Compiler November 2012 CTP或更高版本的 Visual Studio 2012,以支持统一的初始化语法。

最佳答案

n4 is a function declarationn3 是由 copy elision 引起的.

检查 here我启用了 -fno-elide-constructors 以避免复制省略。 n3 然后显示一系列复制和 move 构造函数。

有一个注释掉的行尝试使用 n4 作为对象。如果取消注释它,您将看到编译器错误,告诉它是一个函数。

对于 n4 不要被解释为函数声明,您可以在临时变量周围放置额外的括号,以防止其被视为函数参数:Number n4((Number(n1) ))。有了这个和 -fno-elide-constructors 你所期望的一切都会发生。

请注意,-fno-elide-constructors 在 MSVC 中不作为选项出现。

关于c++11 - 无法运行 move 构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15151765/

相关文章:

c++ - 对于使用输出参数函数来初始化 const 成员的构造函数中的调用,代码比 lambda 更简单

c++ - 没有默认构造函数会导致没有 move 构造函数吗?

python - 花括号的含义是什么?

c++ - 多个快速读取器单个慢速写入器 : is using shadow-data with atomic index safe?

c++ - 在模板派生类中继承具有类型别名的构造函数

c++ - boost::lexical_cast 对于 c++11 stoi、stof 和 family 是否是多余的?

join - vim:如何在没有空格的情况下连接开/关大括号

c++ - 为什么在返回兼容类型时需要显式 std::move?

c++ - 通过引用或值枚举类 C++11

c - 在 C 字符串中转义大括号