Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
匹配一个C++;模板中的lambda表达式 我试图在C++模板中匹配可调用对象,并根据接收到的可调用对象的类型提供不同的实现。p>_C++_Templates_Lambda_Std Function - Fatal编程技术网

匹配一个C++;模板中的lambda表达式 我试图在C++模板中匹配可调用对象,并根据接收到的可调用对象的类型提供不同的实现。p>

匹配一个C++;模板中的lambda表达式 我试图在C++模板中匹配可调用对象,并根据接收到的可调用对象的类型提供不同的实现。p>,c++,templates,lambda,std-function,C++,Templates,Lambda,Std Function,我有以下模板功能: template<class Ret, class... Args> void fun(std::function<Ret(Args...)> f) {} template<class Ret, class... Args> void fun(Ret(*f)(Args...)) {} 导致编译错误。实现接受匿名lambda函数的模板表达式的正确方法是什么?也许一种方法是检查正在传递的类是否有操作符()方法?转换在模板参数替换之后发生。l

我有以下模板功能:

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

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

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

转换在模板参数替换之后发生。lambda的类型不是
std::function
,而是匿名类型。实际上,为了接收任何可调用的对象,您需要接收匿名lambda

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

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

template<typename F>
auto fun(F f) -> void_t<decltype(&T::operator())> {
    // ...
}
decltype
中的表达式必须有效才能使函数存在

如果你想让你的代码处理更多的类型,你必须提供一个重载,你可以指定参数。现在,检查很容易实现:

// Another overload of your function
template<typename F, typename... Args>
auto fun(F f) -> void_t<decltype(f(std::declval<Args>()...)> {
    // ...
}
//函数的另一个重载
模板
自动娱乐(F)->void\u t{
// ...
}

这样,它也适用于一般的lambda和重载操作符。

这是有效的C++代码,而C++ 14级的GCC 6.1.1将支持我:
template<typename F>
void foo(F &&f)
{
}

void bar()
{
    auto lambda=[](auto a, auto b) {};

    foo(lambda);
}
模板
无效foo(F&F)
{
}
空条()
{
自动λ=[](自动a,自动b){};
foo(lambda);
}
如您所见,模板不可能推断lambda的参数。lambda的参数类型在使用之前是未知的


你可以推断某些东西有一个
操作符()
,正如另一个答案所示,但这几乎就是它的全部。

用非推断的
参数调用
乐趣将是丑陋的。。。并要求将lambda存储在变量中以获取其类型:-/的确,但这可能会让OP了解如何限制其函数。我不确定我是否理解您的意思。为什么这不是一个推导lambda参数的示例:。
// Another overload of your function
template<typename F, typename... Args>
auto fun(F f) -> void_t<decltype(f(std::declval<Args>()...)> {
    // ...
}
template<typename F>
void foo(F &&f)
{
}

void bar()
{
    auto lambda=[](auto a, auto b) {};

    foo(lambda);
}