为什么在 C++0x 右值引用的前向定义中使用标识?

发布于 2024-10-28 21:57:17 字数 463 浏览 7 评论 0原文

右值引用简介中,forward定义如下:

  template <typename T>
  struct identity { typedef T type; };

  template <typename T>
  T &&forward(typename identity<T>::type &&a) { return a; }

目的是什么identity 类执行什么操作?为什么不:

  template <typename T>
  T &&forward(T &&a) { return a; }

In A Brief Introduction to Rvalue References, forward is defined as follows:

  template <typename T>
  struct identity { typedef T type; };

  template <typename T>
  T &&forward(typename identity<T>::type &&a) { return a; }

What purpose does the identity class perform? Why not:

  template <typename T>
  T &&forward(T &&a) { return a; }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

无声静候 2024-11-04 21:57:17

identity 的目的是使 T 不可推导。也就是说,强制客户端在调用 forward 时显式提供 T

forward(a);     // compile-time error
forward<A>(a);  // ok

这是必要的原因是因为模板参数是开关,客户​​端通过它告诉编译器将参数作为左值或右值转发。如果您不小心忘记提供此信息,则左值始终作为左值返回,右值始终作为右值返回。虽然一开始这听起来像是您想要的,但实际上并非如此。

template <class T, class A1>
std::shared_ptr<T>
factory(A1&& a1)
{
    return std::shared_ptr<T>(new T(std::forward<A1>(a1)));
}

在上面的示例中,a1 始终是左值。但“开关”A1 可能是也可能不是左值引用。如果它是左值引用,a1 将作为左值返回,否则 a1 将作为右值返回。如果工厂的作者不小心忘记提供A1,使用identity会在编译时提醒他。

注意:最终草案缺少 identity,但出于相同目的在同一位置使用 remove_reference

The purpose of identity was to make T non-deducible. That is, to force the client to explicitly supply T when calling forward.

forward(a);     // compile-time error
forward<A>(a);  // ok

The reason this is necessary is because the template parameter is the switch with which the client tells the compiler to forward the argument as either an lvalue or as an rvalue. If you accidentally forget to supply this information then lvalues are always returned as lvalues and rvalues are always returned as rvalues. While at first that may sound like what you want, it really isn't.

template <class T, class A1>
std::shared_ptr<T>
factory(A1&& a1)
{
    return std::shared_ptr<T>(new T(std::forward<A1>(a1)));
}

In the above example a1 is always an lvalue. But the "switch" A1 may or may not be an lvalue reference. If it is an lvalue reference, a1 gets returned as an lvalue, otherwise a1 gets returned as an rvalue. If the author of factory accidentally forgets to supply A1, the use of identity reminds him at compile time.

Note: The final draft lacks identity, but uses remove_reference in the same place for the same purpose.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文