【问题标题】:std::move(std::array) g++ vs visual-c++std::move(std::array) g++ vs visual-c++
【发布时间】:2017-07-31 12:28:01
【问题描述】:

我在 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============
复制构造
移动构造
=========2============
移动构造
移动构造
=========3============
移动构造
移动构造

当我在 Visual Studio 2013 中尝试(实际上)相同的代码时,结果不同:

输出:

=========1============
复制构造
移动构造
=========2============
复制构造
复制构造
=========3============
复制构造
复制构造

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

【问题讨论】:

  • OT,由于不必要的stdafx.h_tmain,您真的需要发布两个代码示例吗?
  • [Off Topic]B(array&lt;A, 2&gt;&amp; a) : m_a(std::move(a)) 不是您想要将某些东西移动到对象中的方式。您将对象留在调用站点中,而没有任何迹象表明它是移动的。
  • @LogicStuff 我想表明我没有做任何不同的事情。
  • @NathanOliver 我会编辑一个更好的版本,我循环了很多构造函数来找到可以工作的东西这是最新的,但确实不是一个好的界面。
  • @turoni -- 我没有反对std::;这是使用标准库中的东西的正确方法。而'\n' std::endl 做同样的事情;它做的更少——它开始新的一行。 (这是一个提示:阅读 std::endl 的实际作用并决定是否需要它)

标签: c++ c++11 visual-studio-2013


【解决方案1】:

这是 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 中移出。

【讨论】:

  • 我刚刚为 B 编辑了更好的构造函数。有什么方法可以在 MSV2013 中得到相同的结果吗?
  • @turoni 不幸的是没有。它只是无法正常工作。
  • @turoni 你可以写一个类型包装std::array,就像继承一样,手动实现移动构造函数。 MSVC2013 永远不会为您编写正确的移动 ctor 并且不会让您 noexcept。 MSVC2017 需要正确的noexcept 才能在std::vectors 中正常工作。这是一个很大的痛苦。
【解决方案2】:

Visual Studio 2013 与 C++11 不完全兼容。对标准容器的移动支持是那些“未完全实现”的部分之一。 您的示例适用于最新版本的 VS2017,请参阅 at Rextester

附: Here您可以获取有关各种编译器中对 C++ 功能的支持的详细信息。

【讨论】:

    猜你喜欢
    • 2014-12-15
    • 1970-01-01
    • 2021-05-26
    • 2016-06-15
    • 2017-05-28
    • 1970-01-01
    • 2016-07-08
    • 2021-08-17
    • 1970-01-01
    相关资源
    最近更新 更多