3

Here's a trivial example of what I'm trying to achieve. Is it even possible to pass lambda into template function?

HEADER FILE

class my_impl {
public:
    template<typename F> void do_something(F && f);
};

CPP FILE

// .cpp file
template<typename F> my_impl::do_something(F && f)
{
    // ... implementation
}

template void my_impl::do_something<std::string &&>(std::string &&); // OK
template void my_impl::do_something<???>(???); // what goes here for lambda?

// used like this
my_impl impl;
impl.do_something( "123" );
impl.do_something( []() { 
   ...
} );
Ragnar
  • 1,387
  • 4
  • 20
  • 29
  • [Why can templates only be implemented in the header file?](http://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file) You can already use it, what you're looking for is how to explicitly instantiate this template. – LogicStuff Dec 19 '15 at 17:15
  • The `// OK` and `// what goes here for lambda` lines are not required at all in your sample code. Delete them and your code compiles. Please be more clear why you think you need them. – Yakk - Adam Nevraumont Dec 19 '15 at 17:19
  • @Yakk note that these are in .cpp file. – Ragnar Dec 19 '15 at 17:21
  • Did you try copy-pasting your sample code above, deleting those two lines, and compilimg? Again, *you still do not need those lines*. I get that there are "nearby" problems where you might need those lines, but post actual code that actually has problems. Before submitting, take your code back to a compiler and make sure it still has the property you want. Pseudo code is useless here. – Yakk - Adam Nevraumont Dec 19 '15 at 17:57
  • @Ragnar: You want to write specialization for a lambda ?! – Jarod42 Dec 19 '15 at 23:49

2 Answers2

0

A lambda is an instance of unique, compiler-generated, internal type.

You can see this for yourself by using your debugger. For example, given the following short snippet of test code:

class my_impl {
public:
    template<typename F> void do_something(F && f);
};

template<typename F> void my_impl::do_something(F && f)
{
}

int main()
{
    my_impl m;

    m.do_something( []() {} );
}

With gcc 5.3, stepping through the debugger, the following results are observed:

main () at t.C:22
22      m.do_something( []() {} );
(gdb) s
my_impl::do_something<main()::<lambda()> >(<unknown type in /tmp/t, CU 0x0, DIE 0x23e>) (this=0x7fffffffe44d, f=<unknown type in /tmp/t, CU 0x0, DIE 0x23e>)
    at t.C:9

Note that gdb reports the template instance as type my_impl::do_something<main()::<lambda()> >. The compiler generated an internal fake type of main()::<lambda()> for the lambda type. Of course, you cannot refer to a type like that.

I do not see a way of refer to a lambda's internal type.

Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148
0

The type of the lambda depends on the lambda itself. You can do

 auto l=[] (/*arguments*/) {/*body*/};
 template void my_impl::do_something<decltype(l)>(decltype(l)&&); 

However this will work only with the lambda l because the compiler generates new type for each lambda.

It can be used like

my_impl impl;
impl.do_something(l);
Abstraction
  • 511
  • 2
  • 9
  • This works for trivial lamba. But I need to capture class member fields and some local variables and these change depending on usage. – Ragnar Dec 19 '15 at 17:47