Template argument deduction

Nov 29, 2012 at 10:57pm
Given the following template:

1
2
template<class T>void luaK_pushiter(lua_State *l, T begin, T end,
 boost::function<void (lua_State *, boost::shared_ptr<T>)> wrapfunc) {


this class:

1
2
3
namespace DB {
class ProblemIterator
{


and this code:

1
2
3
4
5
6
7
8
9
void pushProblemIterator(lua_State *l, boost::shared_ptr<DB::ProblemIterator> pi) {
    lua_pushstring(l, (*pi)->name().c_str());
}

static int probIterator(lua_State *l) {
    luaK_pushiter(l, DB::ProblemIterator(""), DB::ProblemIterator(),
     pushProblemIterator);
    return 1;
}


Why can's T be deduced? i.e. why do I get this error?

1
2
localpdb_capi.cc: In function ‘int probIterator(lua_State*)’:
localpdb_capi.cc:74: error: no matching function for call to ‘luaK_pushiter(lua_State*&, DB::ProblemIterator, DB::ProblemIterator, void (&)(lua_State*, boost::shared_ptr<DB::ProblemIterator>))’


Whereas, if I specify the template, it works fine

1
2
3
4
5
static int probIterator(lua_State *l) {
    luaK_pushiter<DB::ProblemIterator>(l, DB::ProblemIterator(""), DB::ProblemIterator(),
     pushProblemIterator);
    return 1;        
}


I think it's got to do with the fact that pushProblemIterator isn't a boost::function<>, but I don't fully understand what's going on.

Thanks.
Nov 29, 2012 at 11:11pm
boost::function (and std::function) is a type-erasing class: there is no direct connection between the type of std::function and the type of the object you're constructing it from.

Normal practice is to template on the functor type

1
2
3
template<class T, class F>
void luaK_pushiter( lua_State *l, T begin, T end, F wrapFunc )
{


Last edited on Nov 30, 2012 at 1:01am
Nov 30, 2012 at 7:16am
Templating on the Functor type as you suggest works fine, but I still don't really understand what's going on. Do you know of a simple-ish article on argument deduction?
Nov 30, 2012 at 5:33pm
To put it simple, implicit conversions are not considered during deduction. They are considered during overload resolution, but to get there, the compiler needs to generate the list of overloads first.
Last edited on Nov 30, 2012 at 5:34pm
Topic archived. No new replies allowed.