c++ - C++参数包扩展
问题描述
下面的代码无法编译(请参阅代码下方的错误)。你能解释一下为什么吗?
template <class F, class... Arg>
void for_each_argument(F f, Arg&&... arg)
{
f(std::forward<Arg>(arg...));
}
int main()
{
for_each_argument(
[](const auto& a){std::cout<< a;}, "Aa", 3, 4);
return 0;
}
这是一条错误消息:
7:4:错误:表达式包含未扩展的参数包“Arg”
f(std::forward(arg...));
解决方案
您的代码中有几个问题。首先,您的原始行
f(std::forward<Arg>(arg...));
根本不是正确的语法 - 您正在扩展而没有在模板中arg
正确扩展。Arg
现在,您至少可以通过以下方式解决此问题
f(std::forward<Arg>(arg)...);
这会更好,但仍然是错误的——你会用 3 个参数调用你的 lambda 一次,而它只接受一个参数——相反,你想用一个参数调用 lambda 3 次。
有几种方法可以做到这一点。首先,也是最不推荐的,是递归调用函数,正如其他答案所暗示的那样。这会提示难看的语法,也增加了递归模板实例化的编译器负担。更好的解决方案是使用数组技巧扩展参数,例如(为简单起见忽略前向):
auto lam = [&f](const auto& a) { f(a); return true;}
bool arr[] = { lam(std::forward<ARG>(arg))... };
(void)arr;
在 C++ 17 中,您可以使用折叠表达式来实现更简洁的语法:
(f(std::forward<ARG>(arg)), ...);
推荐阅读
- java - 从 Java 连接 Elasticsearch 时获取 java.net.ConnectException
- python - 如何在 Flask 中创建带有复选框的数组
- google-app-maker - Google App Maker:以编程方式更改计算的数据源查询页面大小
- bash - 在 Bash 的 for 循环中使用 if 的算术比较运算符
- jquery - 如何使用 .done() 和 .then() 将嵌套的 jQuery Promises 转换为平面代码结构
- dji-sdk - 完成 DJIWaypointMission 中的航路点后,让无人机悬停超过 32,767 毫秒
- python - 用于循环的python单位矩阵
- sas - 数据不存在
- database-design - 消失时间序列的替代方案:时间序列数据库建模
- android - 使用 Intent 在 Android 上的 Tiktok 应用中打开用户页面