std::move(std::array) g++ 与 visual-c++

std::move(std::array) g++ vs visual-c++

我在 visual studio 2013 的项目中为我的 std::array 中的元素实现移动构造函数时遇到了一些问题。

所以我尝试在用 g++ 5.3.0 编译的 notepad++ 中制作一个最小示例。
才发现在 g++ 中我可以做我想做的事

示例 g++:

#include <iostream>
#include <array>

using namespace std;

struct A{
    A() = default;
    A(const A&)
    {
        cout << "copy constructed" << endl;
    }
    A(A&&)
    {
        cout << "move constructed" << endl;
    }
};

class B{
public:
    B(array<A, 2>&& a)
      : m_a(std::move(a))
    {}
private:
    array<A, 2> m_a;
};

int main(){
    A foo;
    cout << "=========1===========" << endl;
    array<A, 2> a = { { foo, std::move(foo) } };
    cout << "=========2===========" << endl;
    B b(std::move(a));
    cout << "=========3===========" << endl;
    array<A, 2> a_second = std::move(a);
    return 0;
}

输出:

=========1===========
copy constructed
move constructed
=========2===========
move constructed
move constructed
=========3===========
move constructed
move constructed

当我在 visual studio 2013 年尝试(几乎)相同的代码时,结果不同:

输出:

=========1===========
copy constructed
move constructed
=========2===========
copy constructed
copy constructed
=========3===========
copy constructed
copy constructed

我如何在visual c++中使用move构造函数,为什么visual c++拒绝在这里使用他?

这是 MSVS 2013 中的错误。MSVS 2013 does not generate implicit move constructors。如果您 运行 在 MSVS 2015 或 2017 中使用它,您将获得相同的输出。


我还要指出

B(array<A, 2>& a) : m_a(std::move(a))

不是您想将对象移动到 B 中的方式。如果你想让 B 接管数组你应该

B(array<A, 2>&& a) : m_a(std::move(a))

这意味着不用

B b(a);

你必须使用

B b(std::move(a));

现在您可以清楚地看到 a 已从 main 中移出。

Visual studio 2013 与 C++11 不完全兼容。对 std 容器的移动支持是 "not fully implemented" 部分之一。 您的示例适用于最新版本的 VS2017,请参阅 at Rextester

P.S。 Here 您可以获得有关各种编译器对 C++ 功能的支持的详细信息。