Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't my C++ compiler deduce template argument for boost function?

Tags:

c++

templates

I define a method like so:

template <class ArgT>
void foo(ArgT arg, ::boost::function< void(ArgT) > func)
{
    func(arg);
}

and use it like this --for instance--:

foo(2, [](int i) -> void { cout << i << endl; });

Why can't the compiler deduce the type since it's definitely an int?

I get 'void foo(ArgT,boost::function<void(ArgT)>)' : could not deduce template argument for 'boost::function<void(ArgT)>' from 'anonymous-namespace'::<lambda0>'.

like image 335
mister why Avatar asked May 03 '11 14:05

mister why


1 Answers

While C++ lambdas are strictly monomorphic, they are merely shorthand for function objects (aka functors), and in general functors can be polymorphic; i.e., their call operators can be overloaded or templated. As a result, functors (and, consequently, lambdas) are never implicitly convertible to templated std::function<> (or boost::function<>) instances because functors' operator() argument types are not automatically inferable.

To phrase it slightly differently, the natural type of your lambda expression is a functor with a parameterless constructor and an operator() with the signature void operator ()(int) const. However obvious this fact may be to you and I, it's not automatically inferrable that ArgT should resolve to int because lambdas are functors and functors' operator()s are possible to overload and template.

TL;DR: What you want isn't possible.

like image 184
ildjarn Avatar answered Oct 24 '22 05:10

ildjarn