Suppose I have a header wrapper.h:
template <typename Func> void wrapper(const Func func);
and a file wrapper.cpp containing:
#include "wrapper.h"
template <typename Func>
void wrapper(const Func func)
{
func();
}
And a file main.cpp containing:
#include "wrapper.h"
#include <iostream>
int main()
{
wrapper( [](){std::cout<<"hello."<<std::endl;} );
}
If I compile these together (e.g., cat wrapper.cpp main.cpp | g++ -std=c++11 -o main -x c++ -), I get no linker errors.
But if I compile them separately (e.g., g++ -std=c++11 -o wrapper.o -c wrapper.cpp && g++ -std=c++11 -o main main.cpp wrapper.o), I --- of course --- get a linker error:
Undefined symbols for architecture x86_64:
"void wrapper<main::$_0>(main::$_0)", referenced from:
_main in main-5f3a90.o
Normally, I could explicitly specialize wrapper and add something like this to wrapper.cpp:
template void wrapper<void(*)()>(void(*)())
But this particular template specialization doesn't work.
Is it possible to specialize a template on a lambda?
First, I assume you know about Why can templates only be implemented in the header file?
To your question:
Is it possible to specialize a template on a lambda?
Unfortunately No, template specializations work with exact match, and a lambda is a unique unnamed type. The problem is specializing for that type which you do not know.
Your best bet is to use std::function; or as you have done, then additionally force the lambda to be converted into a function pointer by adding +
int main()
{
wrapper(+[](){std::cout<<"hello."<<std::endl;} );
}
Full example:
#include <iostream>
template <typename Func>
void wrapper(const Func func)
{
std::cout << "PRIMARY\n";
func();
}
template <>
void wrapper<void(*)()>(void(*func)())
{
std::cout << "SPECIALIZATION\n";
func();
}
int main()
{
wrapper([](){std::cout<<"hello\n"<<std::endl;} );
wrapper(+[](){std::cout<<"world."<<std::endl;} );
}
This will print
PRIMARY
hello
SPECIALIZATION
world
Also, decltype facility wouldn't help, if it does, it will take away the flexibility of your need for lambda
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With