c++ - 将参数包传递给另一个可变参数模板函数时是否必须使用 std::forward
问题描述
如何实现将参数包传递给函数(bar)的函数(foo),函数(bar)最终将该参数包传递给类构造函数?这是代码:
template <typename... Args>
void bar(Args&&... args)
{
MyObj obj(std::forward<Args>(args)...);
/* Do something with obj */
}
我是否必须将 foo 实现为
template <typename... Args>
void foo(Args&&... args)
{ bar(args...); }
或者
template <typename... Args>
void foo(Args&&... args)
{ bar(std::forward<Args>(args)...); }
解决方案
你需要使用forward
. forward
看起来像这样:
template <class T>
constexpr T&& forward(typename std::remove_reference<T>::type& t) noexcept
{
return static_cast<T&&>(t);
}
(还有另一个重载forward
,但在这里无关紧要。)
Arg
对于模板参数包的每个元素Args
,Arg
可以是:(T
是非引用类型)
T&
如果参数是非常量左值,则参数的类型为T&
; 或者const T&
如果参数是 const 左值,则参数的类型为const T&
; 或者T
如果参数是右值,则参数的类型为T&&
。
在第一种情况下,forward<Arg>(arg)
实例化为:
constexpr T& forward(T& t) noexcept
{
return static_cast<T&>(t);
}
导致要传递的非常量左值。
在第二种情况下,forward<Arg>(arg)
实例化为:
constexpr const T& forward(const T& t) noexcept
{
return static_cast<const T&>(t);
}
导致要传递的 const 左值。
在最后一种情况下,forward<Arg>(arg)
实例化为:
constexpr T&& forward(T&& t) noexcept
{
return static_cast<T&&>(t);
}
导致要传递的右值。
在所有这三种情况下,值类别都被保留,并且值被修改后转发到bar
.
如果您不使用forward
,您将无条件地传递一个左值,这是不希望的。
推荐阅读
- javascript - 猫鼬查找没有空数组的集合
- python - 为什么品脱要创建第二个注册表?
- javascript - vue js - 从纯文本到 vue 组件的 HTML 注入
- javascript - 如何在打开(Firefox)网络扩展的弹出页面时调试网络请求?
- javascript - 将 JavaScript 正则表达式函数转换为 php
- python - 在不使用第三方库的情况下旋转图像?
- python - mysql.connector 库不适用于heroku
- f# - F# 用扑克牌创建手
- php - 使用用户名或电子邮件登录 Laravel fortify 验证失败
- django - 添加 django 子模型时发送信号的问题