下面的代码无法编译(请参阅代码下面的错误)。你能解释一下为什么吗?
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;
}
Run Code Online (Sandbox Code Playgroud)
这是一条错误消息:
7:4:错误:表达式包含未扩展的参数包“Arg”
f(std::forward(arg...));
您的代码中有几个问题。首先,你原来的行
f(std::forward<Arg>(arg...));
Run Code Online (Sandbox Code Playgroud)
根本不正确的语法 - 您正在扩展arg而没有在模板中正确扩展Arg。现在,您至少可以通过以下方式解决这个问题
f(std::forward<Arg>(arg)...);
Run Code Online (Sandbox Code Playgroud)
这会更好,但仍然是错误的 - 您将使用 3 个参数调用 lambda 一次,而它只接受一个 - 相反,您想使用单个参数调用 lambda 3 次。
做这件事有很多种方法。首先,也是最不推荐的,是递归调用该函数,正如其他答案所暗示的那样。这会导致语法丑陋,并且还会增加编译器递归模板实例化的负担。更好的解决方案是使用数组技巧来扩展参数,例如(为了简单起见,忽略前向):
auto lam = [&f](const auto& a) { f(a); return true;}
bool arr[] = { lam(std::forward<ARG>(arg))... };
(void)arr;
Run Code Online (Sandbox Code Playgroud)
在 C++ 17 中,您可以使用折叠表达式来实现更简洁的语法:
(f(std::forward<ARG>(arg)), ...);
Run Code Online (Sandbox Code Playgroud)