std::move 实现
我从 microsoft
template <typename T> struct RemoveReference {
typedef T type;
};
template <typename T> struct RemoveReference<T&> {
typedef T type;
};
template <typename T> struct RemoveReference<T&&> {
typedef T type;
};
template <typename T> typename RemoveReference<T>::type&& Move(T&& t) {
return t;
}
...
remote_integer x = frumple(5);
remote_integer&& x1 = Move(x);
我收到错误“错误 C2440: 'return' : 无法从 'remote_integer' 转换为'remote_integer &&'"
编译器中发生了一些变化?使用 std::move 一切顺利。
I got next snippet from microsoft
template <typename T> struct RemoveReference {
typedef T type;
};
template <typename T> struct RemoveReference<T&> {
typedef T type;
};
template <typename T> struct RemoveReference<T&&> {
typedef T type;
};
template <typename T> typename RemoveReference<T>::type&& Move(T&& t) {
return t;
}
...
remote_integer x = frumple(5);
remote_integer&& x1 = Move(x);
and i get an error "error C2440: 'return' : cannot convert from 'remote_integer' to 'remote_integer &&'"
something changed in compilers? With std::move all goes right.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
Move
不起作用的原因是t
始终是 左值(即使当T&&
例如,解析为int&&
)。尽管看起来很奇怪,命名的右值引用确实是左值。从
Move
返回时,您尝试将左值隐式绑定到右值引用,这是标准 (§8.5.3) 所禁止的。正如评论中所指出的,您必须显式地将t
转换为右值引用。标准的相关部分是 §5/4 和 §5/5,但我将引用注释 §5/6,它很好地总结了这一点:
正确的实现确实是:
据我记得,这段代码在早期的草稿中曾经有效。但由于规则已更改,您现在必须提供显式强制转换(同样适用于 std::forward)。
The reason your
Move
doesn't work, is becauset
is always lvalue (even whenT&&
resolves to, say,int&&
). Even though it might seem weird, named rvalue references are indeed lvalues.When returning from your
Move
, you attempt to implicitly bind lvalue to rvalue reference, which is forbidden by standard (§8.5.3). As noted in the comments, you have to castt
explicitly to rvalue reference.Relevant parts of standard are §5/4 and §5/5, but I'm going to quote note §5/6, which sums this nicely:
Correct implementation is indeed:
As far as I remember, this code used to be valid in earlier drafts. But since the rules have changed, you have to provide explicit cast now (same applies to std::forward).