将 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 正确地一个接一个地接收参数。但是,accn 没有被修改。怎么会?

您需要调用 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)...);