【问题标题】:Type of lambda with parameter pack带参数包的 lambda 类型
【发布时间】:2022-12-08 09:35:24
【问题描述】:

考虑以下 (https://godbolt.org/z/sfT3aesvK):

#include <utility>
#include <vector>

struct A { constexpr static int type = 0; };

template <typename Func, typename... Args>
int foo(Func func, Args&& ... args) {
    auto call_with_A = [func](Args&& ... args) {
        return func.template operator()<A>(std::forward<Args>(args)...);
    };
    std::vector<int(*)(Args&&...) /* what goes here? */> vec{{call_with_A}};
    int acc = 0;
    for (auto fn : vec) {
        acc += fn(std::forward<Args>(args)...);
    }
    return acc;
}

int bar() {
    return 1 + foo([]<typename T>(int a, int b) {
        return T::type + a + b;
    }, 2, 3);
}

以上不编译,因为

no known conversion from '(lambda at <source>:8:24)' to 'int (*)(int &&, int &&)' for 1st argument

我的问题是T 的模板类型是什么,以便std::vector&lt;T&gt; 将接受call_with_A 作为元素?

我试图打印 decltype(call_with_A) 是什么,但这似乎只是编译器的 (lambda at [...]) 表达式。

【问题讨论】:

  • 您不能将捕获的 lambda 转换为函数指针。您可以将其转换为 std::function
  • 即使捕获的参数是 constexpr,这是否适用?我想在 constexpr 设置中评估所有内容,但我似乎无法使用 std::function
  • 它适用于所有捕获的 lambda。
  • 你想用该代码实现什么?为什么你有那个vector?如果你真的要在那个向量中有多个函数,那么在调用函数时转发参数可能不是一个好主意。

标签: c++ templates lambda c++20 variadic-templates


【解决方案1】:

lambda 表达式的类型是“unutterable”。不能直接写下来。但是,您可以为该类型声明一个 typedef 别名:

auto call_with_A = /* lambda */;
using LambdaType = decltype(call_with_A);
std::vector<LambdaType> vec = {call_with_A};

如果您无论如何都不需要提及类型,也可以使用类模板参数推导:

auto call_with_A = /* lambda */;
std::vector vec = {call_with_A};
// the type of `vec` is `std::vector<decltype(call_with_A)>`

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-06
    • 1970-01-01
    • 2021-07-31
    • 1970-01-01
    相关资源
    最近更新 更多