【发布时间】: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 修复了这个错误。