为什么编译器无法推断出此函数模板?
Why can't the compiler deduce to this function template?
我们有一个函数,它将函数对象作为参数。函数有两个重载,它们在函数签名上有所不同。
#include <functional>
template <typename T>
void foo(std::function<void(T)> bar)
{
}
template <typename T>
void foo(std::function<void(int, T)> bar)
{
}
int main()
{
foo([](float number) {
});
return 0;
}
但是,此代码不会编译。
error C2784: 'void foo(std::function<void(int,T)>)' : could not deduce template argument for 'std::function<void(int,T)>' from 'main::<lambda_2b4e4413ec419a4ac179a0b64ebde221>' : see declaration of 'foo'
error C2784: 'void foo(std::function<void(T)>)' : could not deduce template argument for 'std::function<void(T)>' from 'main::<lambda_2b4e4413ec419a4ac179a0b64ebde221>' : see declaration of 'foo'
我认为模板本身和过载都有问题。如何提供与上述签名匹配的两个函数?
这也意味着,如果不使用模板,就无法传递lambda,因为没有lambda类型。Lambda既不是std::function
(也不是从它派生的),也不是函数指针。它们是实现应用程序运算符的唯一类型,即operator()
。
您可以使用static_cast运算符来执行此操作
template <typename T>
void foo(std::function<void(T)> bar)
{
}
foo( static_cast< std::function<void(float)> >( [](float number){}));
//or
foo( std::function<void(float)>{ [](float){} } );
原因显然是每个lambda表达式都有自己的类型的副作用之一。
例如,这意味着您不能声明lambda参数或指向lambda的指针。这也意味着,当需要类型推导时(例如,用于模板实例化),不能使用lambda。
解决方案是尽快将lambda封装到std::function<...>
对象中,因为这些对象具有可以在模板中指定和匹配的类型。
例如,不能有返回lambda的函数,也不能将lambda存储在成员中。。。但您可以返回一个std::function
或将std::function
存储到成员中。
在特定情况下,您的代码与一起工作
foo(std::function<void(float)>([](float number){});
相关文章:
- '尝试解析可变参数模板时无法推断出'T的模板参数
- 在实例化之前推断函数模板的返回类型
- 是否可以从构造函数自动推断基类模板参数?
- 根据模板函数类型推断变量的类型
- 为什么编译器不能从返回类型中推断出模板参数?
- std::sort / 适用于测试代码,但无法推断出模板
- 无法从'int'中推断出'Node<T> *'的模板参数
- 是否可以推断出模板功能中的参数类型
- 无法从'std::string'中推断出'const std::reverse_iterator<_RanIt> &'的模板参数
- 函数模板参数推断使用 std::Optional 失败
- 如何允许编译器推断出正确的返回类型以进行模板get函数
- 从函数参数推断模板类型
- 如何使模板化运算符推断出正确的返回类型
- 有没有办法从基类函数参数中推断出模板参数
- 错误:调用"反向"没有匹配函数:候选模板被忽略:推断出参数的冲突类型
- 无法推断出嵌套类型的模板函数
- 为什么编译器无法推断出此函数模板?
- 为什么我不能推断出这个函数的模板参数?
- 为什么编译器不能从函数参数中推断出我的模板值?
- 为什么 gcc 无法为我的函数模板推断出正确的类型?