为什么我的交换方法会干扰make_move_iterator
Why is my swap method interfering with make_move_iterator?
这个让我彻底困惑。在下面的示例中,我收到错误:
错误 C2664: 'void std::unique_ptr<_Ty>::swap(std::unique_ptr<_Ty> &&)' :无法将参数 1 从"const std::unique_ptr<_Ty>"转换为 'std::unique_ptr<_Ty> &&'
我不知道它是如何在我的交换功能上结束的,或者为什么它是一个问题。有趣的是,如果我更改如果我更改void swap(const one& other)
的签名并删除常量以void swap(one& other)
一切正常。void swap(const one& other)
的签名并删除常量以void swap(one& other)
它在VS2010中编译,但在GCC中仍然被破坏。如果没有交换重载,则没有问题。
//-----------------------------------------------------------------------------
class one
{
public:
one(){}
one(one&& other) : x(std::move(other.x)) {}
one& operator=(one&& other){ x = std::move(other.x); return *this; }
void swap(const one& other){ x.swap(other.x); }
void swap(one&& other){ x.swap(std::move(other.x)); }
private:
one(const one&);
one& operator=(const one&);
std::unique_ptr<int> x;
};
//-----------------------------------------------------------------------------
void swap(one& left, one& right)
{
left.swap(right);
}
//-----------------------------------------------------------------------------
void swap(one&& left, one& right)
{
right.swap(std::move(left));
}
//-----------------------------------------------------------------------------
void swap(one& left, one&& right)
{
left.swap(std::move(right));
}
//-----------------------------------------------------------------------------
class two
{
public:
two(){}
two(two&&){}
two& operator=(two&&){ return *this; }
operator one(){return one();}
private:
two(const two&);
two& operator=(const two&);
};
//-----------------------------------------------------------------------------
int main()
{
std::vector<two> twos(10);
std::vector<one> ones(std::make_move_iterator(twos.begin()), std::make_move_iterator(twos.end()));
}
编辑:非恒定性要求是有道理的。完全是我的疏忽。为什么它首先调用交换?
(作为参考,我使用的是VS2010)
它的演示坏了
它的演示仍然损坏,但此"修复"在VS2010中有效
// other can't be const since swap modifies it
void swap(one& other){ x.swap(other.x); }
// Why swapping? (swap on rvalues don't work either since it's pointless.)
//Just move the other
void swap(one&& other){ x = std::move(other.x); }
完整的错误消息如下(我引入了一些换行符来防止水平滚动):
error C2664: 'void std::unique_ptr<_Ty>::swap(std::unique_ptr<_Ty> &&)' : cannot convert parameter 1 from 'const std::unique_ptr<_Ty>' to 'std::unique_ptr<_Ty> &&' with [ _Ty=int ] Conversion loses qualifiers
错误发生在代码的以下行上:
void swap(const one& other){ x.swap(other.x); }
other
是常量限定的,但std::unique_ptr::swap
需要一个非常量参数。 因此,"转换会失去限定符"(特别是常量限定符)。
这对我来说似乎很简单。交换两个对象时,它们都不是只读的。它们都应该是可修改的,只有这样才能进行交换。
因此,您的swap
函数必须采用非常量引用。
请注意,std::unique_ptr<T>
没有swap
函数,该函数采用右值引用。事实上,拥有一个甚至没有多大意义。VS2010在这方面是非标准的。标准 (§20.7.1.2) 仅要求具有此签名:
void swap(std::unique_ptr<T> &) noexcept;
没有用于右值引用的swap
。我还建议您删除采用右值引用的掉期。它增加了代码不必要的复杂性。
- 瓦尔格林德:数学函数"Conditional jump or move depends on uninitialised value(s)"
- Usages of std::move
- 在C++中对T*类型执行std::move的意外行为
- 关于std::move的使用,是否有编译警告
- 我应该实现右值推送功能吗?我应该使用std::move吗
- VS Code "command":"make"与终端窗口中的命令行"make"不同
- 通过实例理解std::move及其目的
- 使用仅使用一次的变量调用的复制构造函数.这可能是通过调用move构造函数进行编译器优化的情况吗
- 是否可以在 C++03 中定义'move-and-swap idiom'等效项
- 返回一个带有 std::move 的对象并链接函数
- '[](std::list& list)<int>{return std::move(list)}(list)' 是否保证将 'list' 留空?
- 使用 make 编译 MPI,几个命名空间错误,例如"错误:未知类型名称'使用'?
- make 命令如何避免重新编译未更改的源文件?
- 为什么字符串的 move() 会改变内存中底层数据的位置?
- MAKE:找不到包含的用户定义的头文件?
- 当 std::move 与 C 样式数组或不移动对象时会发生什么
- 为什么当我为 for(auto& it : myUnorderedMap) {... = std::move(it.second)} 时,我会得到一个 const 引用?
- 'make check' GLIBC 运行时的链接问题
- 添加自定义析构函数时,Move 构造函数在派生类中消失
- 将向量从 N1 缩小到 N2 项,而不触发默认构造函数并仅使用 move 语义