查看 Scott Meyer 的 Effective Modern C++ pages 200-201,建议的 std::forward
的简化实现可能是(确实在其他地方看到了正确的实现):
template <typename T>
T&& forward(std::remove_reference_t<T>& param)
{ return static_cast<T&&>(param); }
当接受一个右值 Widget 时,它变成:
Widget&& forward(Widget& param)
{ return static_cast<Widget&&>(param); }
现在,如果您使用该替换代码,然后执行以下操作:
struct Widget { };
Widget&& forward(Widget& param)
{ return static_cast<Widget&&>(param); }
template <typename T>
void G(T&& uref)
{ }
template <typename T>
void F(T&& uref)
{ G(forward(uref)); }
int main()
{
Widget x;
F(std::move(x));
}
我无法理解并且还没有看到关于 SO 的直接答案是:在
forward
中参数Widget& param
如何设法接受Widget&&
从 F()?通常 gcc-5.0 会像这样提示非模板代码:error: invalid initialization of non-const reference of type ‘Widget&’ from an rvalue of type ‘std::remove_reference::type {aka Widget}’
(Question #27501400 几乎触及了这个话题,但并不完全。它显示标准同时具有左值 & 和右值 && 版本。)
最佳答案
"Named rvalue references are lvalues",
所以示例工作正常,如评论中所述。
尽管如此,您的代码可以修改为
template <typename T>
void F(T && uref)
{
G(forward(move(uref)));
}
被另一个重载(比较)接受:
template<typename T>
T && forward(typename std::remove_reference<T>::type & t)
{
return static_cast<T &&>(t);
}
template<typename T>
T && forward(typename std::remove_reference<T>::type && t)
{
static_assert(!std::is_lvalue_reference<T>::value, "T is an lvalue reference");
return static_cast<T &&>(t);
}
第二个重载将用于右值。如果
T
则有效是 Widget
或 Widget &&
并且 Widget &
的断言失败.
关于c++ - 在 std::forward 它如何接受右值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29041246/