2

C++11

我在使用移动构造函数时遇到问题。我有一个简单的容器类,叫做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{n1}_ 然后我期望通过使用临时对象调用移动构造函数来构造。Number n3{Number{n1}}NumberNumbern1Number n3

对 D 部分的期望:

由于这类似于 C 部分,除了使用括号而不是花括号外,我希望这部分的行为和输出方式与我期望 C 部分相同。

问题:

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

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

4

1 回答 1

3

n4 是一个函数声明n3是由复制省略引起的。

在这里检查我是否已启用-fno-elide-constructors以避免复制省略。n3然后显示一系列复制和移动构造函数。

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

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

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

于 2013-03-01T07:03:07.477 回答