c++ - 将 lambda 应用于模板参数包;未捕获 lambda 参数

标签 c++ c++11 variadic-templates

我想编写一个函数来接受任意数量的数字参数并返回它们的平均值。使用来自 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 没有返回值,您还需要提供一个值以传递给 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,gcc 无法编译上述内容(另请参见 https://stackoverflow.com/a/13444602/34509)。一种解决方法是在 lambda 之外扩展参数包:

detail::iterate_template_pack((([&](ResultType&& r){
    acc += r;
    ++n;
}(args)), void(), 0)...);

关于c++ - 将 lambda 应用于模板参数包;未捕获 lambda 参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28626315/

相关文章:

c++ - 我似乎无法弄清楚我的代码出了什么问题,我无法获得输出

c++ - 如何从可变参数宏正确调用可变参数模板函数?

c++ - 从函数返回 boost streambuf

c++ - 如何获取文件名

c++11 - C++ 中的双 & 符号。 (第一个声明在 func 参数上,第二个声明在变量之前)

c++ - 类型检测 : using variadic arguments to properly implement a function that calculates the mean

c++ - 带有类模板的可变参数模板的特化

c++ - 使用指向 "return"多维数组的函数指针

c++ - 如何向集合中插入一个新值并同时删除另一个值?

c++ - lambda 的类型是什么?