将 lambda 应用于模板参数包;未捕获 lambda 参数
Applying a lambda to template arguments pack; lambda arguments not captured
我想编写一个函数来接受任意数量的数字参数和 return 它们的平均值。使用来自 Wikipedia:
的扩展技巧
namespace detail
{
template<typename... Args> void iterate_template_pack(Args&&...) {}
}
template <typename ResultType, typename... Args>
ResultType arithmeticMean(Args&&... args)
{
ResultType acc = ResultType(0);
size_t n = 0;
detail::iterate_template_pack(([&](){
acc += ResultType(args);
++n;
})...);
return acc / n;
}
这可以编译并且几乎可以工作:我可以看到 lambda 正确地一个接一个地接收参数。但是,acc
和 n
没有被修改。怎么会?
您需要调用 lambda,否则您只是将一系列 lambda 对象传递给 iterate_template_pack
:
detail::iterate_template_pack(([&](){
acc += ResultType(args);
++n;
})()...);
^^
由于您的 lambda 没有 return 值,您还需要提供一个值以传递给 iterate_template_pack
,因为您不能将 void
作为参数传递:
detail::iterate_template_pack((([&](){
acc += ResultType(args);
++n;
})(), void(), 0)...);
From Wikipedia(我强调):
Instead of executing a function, a lambda expression may be specified and executed in place, which allows executing arbitrary sequences of statements in-place.
pass{([&]{ std::cout << args << std::endl; }(), 1)...};
请注意,由于 PR 47226 (see also ),gcc 无法编译上述内容。一种解决方法是在 lambda 之外扩展参数包:
detail::iterate_template_pack((([&](ResultType&& r){
acc += r;
++n;
}(args)), void(), 0)...);
我想编写一个函数来接受任意数量的数字参数和 return 它们的平均值。使用来自 Wikipedia:
的扩展技巧namespace detail
{
template<typename... Args> void iterate_template_pack(Args&&...) {}
}
template <typename ResultType, typename... Args>
ResultType arithmeticMean(Args&&... args)
{
ResultType acc = ResultType(0);
size_t n = 0;
detail::iterate_template_pack(([&](){
acc += ResultType(args);
++n;
})...);
return acc / n;
}
这可以编译并且几乎可以工作:我可以看到 lambda 正确地一个接一个地接收参数。但是,acc
和 n
没有被修改。怎么会?
您需要调用 lambda,否则您只是将一系列 lambda 对象传递给 iterate_template_pack
:
detail::iterate_template_pack(([&](){
acc += ResultType(args);
++n;
})()...);
^^
由于您的 lambda 没有 return 值,您还需要提供一个值以传递给 iterate_template_pack
,因为您不能将 void
作为参数传递:
detail::iterate_template_pack((([&](){
acc += ResultType(args);
++n;
})(), void(), 0)...);
From Wikipedia(我强调):
Instead of executing a function, a lambda expression may be specified and executed in place, which allows executing arbitrary sequences of statements in-place.
pass{([&]{ std::cout << args << std::endl; }(), 1)...};
请注意,由于 PR 47226 (see also ),gcc 无法编译上述内容。一种解决方法是在 lambda 之外扩展参数包:
detail::iterate_template_pack((([&](ResultType&& r){
acc += r;
++n;
}(args)), void(), 0)...);