gpt4 book ai didi

c++ - 在模板中匹配 C++ lambda 表达式

转载 作者:太空狗 更新时间:2023-10-29 20:36:09 24 4
gpt4 key购买 nike

我正在尝试匹配 C++ 模板中的可调用对象,并根据作为参数接收的可调用对象的类型提供不同的实现。

我有以下模板函数:

template<class Ret, class... Args>
void fun(std::function<Ret(Args...)> f) {}

template<class Ret, class... Args>
void fun(Ret(*f)(Args...)) {}

它们接受std::function 对象和普通函数指针,并正确地推断出它们的返回Ret 和参数Args 类型。但是,我在传递匿名 lambda 表达式时遇到了困难,因为它们与上面的任何模板都不匹配。

调用类似的东西

fun([](int x, int y){return x + y;})

导致编译错误。实现接受匿名 lambda 函数的模板表达式的正确方法是什么?也许一种方法是检查正在传递的类是否具有 operator() 方法?

最佳答案

转换发生在模板参数替换之后。 lambda 的类型不是 std::function,而是匿名类型。事实上,您将收到一个匿名 lambda 以接收任何可调用对象。

您似乎关心的是限制接收到的对象具有 operator() 定义。这个问题很容易用表达式 sfinae 解决。但是,由于您没有接收参数,因此将更难检查表达式是否有效。

这不是一般示例,但它适用于任何没有 auto 作为其参数之一的 lambda,或任何具有 operator() 的对象没有重载:

template<typename F>
auto fun(F f) -> void_t<decltype(&T::operator())> {
// ...
}

void_t 实现如下:

template<typename...>
using void_t = void;

decltype 中的表达式必须有效才能使函数存在。

如果您希望您的代码适用于更多类型,则必须提供可以指定参数的重载。检查现在很容易实现:

// Another overload of your function
template<typename F, typename... Args>
auto fun(F f) -> void_t<decltype(f(std::declval<Args>()...)> {
// ...
}

这样,它也适用于通用 lambda 和重载运算符。

关于c++ - 在模板中匹配 C++ lambda 表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39714375/

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