Failure to deduce template argument std::function from lambda function

半世苍凉 提交于 2019-12-01 00:25:22

A std::function is not a lambda, and a lambda is not a std::function.

A lambda is an anonymous type with an operator() and some other minor utility. Your:

auto foo = [](int i) {
    std::cout << i << std::endl;
};

is shorthand for

struct __anonymous__type__you__cannot__name__ {
  void operator()(int i) { 
    std::cout << i << std::endl;
  }
};
__anonymous__type__you__cannot__name__ foo;

very roughly (there are actual convert-to-function pointer and some other noise I won't cover).

But, note that it does not inherit from std::function<void(int)>.


A lambda won't deduce the template parameters of a std::function because they are unrelated types. Template type deduction is exact pattern matching against types of arguments passed and their base classes. It does not attempt to use conversion of any kind.


A std::function<R(Args...)> is a type that can store anything copyable that can be invoked with values compatible with Args... and returns something compatible with R.

So std::function<void(char)> can store anything that can be invoked with a char. As int functions can be invoked with a char, that works.

Try it:

void some_func( int x ) {
  std::cout << x << "\n";
}
int main() {
  some_func('a');
  some_func(3.14);
}

std::function does that some conversion from its signature to the callable stored within it.


The simplest solution is:

template <class F, class T>
void call(F f, T v) {
  f(v);
}

now, in extremely rare cases, you actually need the signature. You can do this in :

template<class T>
void call(std::function<void(T)> f, T v) {
  f(v);
}
template<class F, class T>
void call(F f_in, T v) {
  std::function f = std::forward<F>(f_in);
  call(std::move(f), std::forward<T>(v));
}

Finally, your call is a crippled version of std::invoke from . Consider using it; if not, use backported versions.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!