gpt4 book ai didi

c++ - 使用参数包将 lambda 转换为 std::function

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:38:33 27 4
gpt4 key购买 nike

关于将 lambda 转换为 std::function 的 SO 有几个问题s,但我还没有看到一个使用参数包作为参数列表的。这在我的 g++ (7.1.1-4) 版本上似乎已损坏,可能只是不受支持。那么这是合法的 c++17(按照标准)吗?如果不是,为什么?

#include <functional>

template <typename TReturn, typename ... TArgs>
void Functor(std::function<TReturn (TArgs...)> f) {}

int main(int argc, char * argv[]) {
auto x = [] (int a, int b) { return a * b; };
Functor<int, int, int>(x);
return 0;
}

上面的代码无法编译,因为它没有通过类型推导。显然明确输入 x作为std::function<int (int, int)>而不是使用 auto使错误消失。但这不允许我将 r 值传递给 Functor如我所愿。我还想通过为函数类型使用另一个模板参数来避免失去任何类型安全性。

我真的不明白为什么上面的代码编译失败,但下面的代码可以正常工作:

#include <functional>

template <typename TReturn, typename TArgA, typename TArgB>
void Functor(std::function<TReturn (TArgA, TArgB)> f) {}

int main(int argc, char * argv[]) {
auto x = [] (int a, int b) { return a * b; };
Functor<int, int, int> (x);
return 0;
}

最佳答案

问题是编译器不知道您打算将 int, int 作为整个 TArgs,因此会尝试推导其余部分TArgs 来自参数 f

例如,这将是有效的:

Functor<int, int, int>(std::function<int(int, int, char, float)>{});
// TArgs := {int, int, [...] char, float}

因此您需要指示编译器不要尝试推导 TArgs 的剩余部分。例如,您可以这样写:

(*Functor<int, int, int>)(x);

或者您可以使用未分解的签名 Sig 编写 Functor:

template <Sig>
void Functor(std::function<Sig> f) {}

或者您可以在非推导上下文中将 TArgs 的使用包装在参数 f 中:

template <typename TReturn, typename ... TArgs>
void Functor(std::function<std::conditional_t<false, void, TReturn (TArgs...)>> f) {}

关于c++ - 使用参数包将 lambda 转换为 std::function,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56583054/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com