【问题标题】:Noncopyable and move constructor不可复制和移动构造函数
【发布时间】:2015-08-14 05:15:07
【问题描述】:

我已经使一个类的成员不可复制,但我已经给它一个移动构造函数和赋值运算符。然而,它并不像矢量这样的容器玩球。

class NonCopyable
{
public:
    NonCopyable(const NonCopyable&) = delete;
    NonCopyable& operator=(const NonCopyable&) = delete;


protected:
    NonCopyable()
    {
    }

    ~NonCopyable() _NOEXCEPT
    {
    }
};


class Member : NonCopyable
{
public:
    Member(int i) : mNum(i)
    {
    }
    ~Member()
    {
    }

    Member(Member&& other) _NOEXCEPT : mNum(other.mNum)
    {
    }

    Member& operator= (Member&& other) _NOEXCEPT
    {
        std::swap(mNum, other.mNum);
        return *this;
    }

private:
    int mNum;
};


struct Item
{
    Item(int i) : mMember(i)
    {
    }

    Member mMember;
};



int _tmain(int argc, _TCHAR* argv[])
{
    std::vector<Item> vec;
    vec.emplace_back(1);

    return 0;
}

以下编译错误:

error C2280: 'NonCopyable::NonCopyable(const NonCopyable &)' : attempting to reference a deleted function
see declaration of 'NonCopyable::NonCopyable'
This diagnostic occurred in the compiler generated function 'Member::Member(const Member &)'

为什么编译器不能识别Member 可以移动?我错过了什么?

编辑:Visual Studio 2013

EDIT2:我将其添加到 Item 并编译:

Item(Item&& other) _NOEXCEPT : mMember(std::move(other.mMember))
{
}

我还好吗?是这样吗?

【问题讨论】:

  • 也适用于clang。微软很可能在再次实施最近的标准方面还没有走得太远。
  • 在 VS2015 上工作正常,但在 VS2013 上不行
  • VS2013 不会为你创建特殊的移动成员函数。因此,Item 既没有移动 ctor 也没有移动赋值运算符。
  • 不要在你自己的代码中使用_NOEXCEPT,这意味着它是MSVC stdlib 实现的私有标识符。不能保证它会存在于较新的版本中,甚至可以扩展到 throw()noexcept 以外的其他内容。要么define your own macro 要么让someone else 努力工作(你想要BOOST_NOEXCEPT_OR_NOTHROW
  • VS2015 修复了这个错误。

标签: c++ c++11 move


【解决方案1】:

在 VS2013 中,部分实现了默认和删除的函数和右值引用。升级到 VS2015,根据 Microsoft 的这些功能已完全实现(您的示例编译良好)。 C++11/14/17 Features In VS 2015 RC

【讨论】:

  • 不仅仅是默认功能实现不完整。 MSVC 甚至没有声明应该在 OP 中为 Item 隐式声明的移动 ctor。它也没有被隐式定义为默认值,但这不会导致 OP 中的错误。
  • @dyp 我已经更新了答案以提及右值引用。
  • 在提到移动特殊成员函数时,我从不喜欢“右值引用”一词的使用。自 VS2010 起,VS 支持将 右值引用 作为类型和表达式,它只是没有隐式声明移动 ctors / 移动赋值运算符。尽管如此,它不仅被 MSVC 使用,而且其他主要编译器实现者在谈论 C++11 支持时暗示移动特殊成员函数:(
猜你喜欢
  • 2023-03-28
  • 1970-01-01
  • 2023-03-20
  • 1970-01-01
  • 2018-09-23
  • 2013-11-05
  • 1970-01-01
  • 1970-01-01
  • 2022-11-21
相关资源
最近更新 更多