I wrote code that extracts types of non-automatic parameters when defining a common lambda function. As you can see in the code below, the idea is to call the connect function with a common lambda and provide arguments for the automatic parameters (which will always be at the beginning in my use case). So in the code below, my goal was to find that the second parameter is of type float.
The code works fine with clang 3.8, but it does not compile with gcc 6.1.1, so I was wondering if this is a bug in gcc or is it just invalid C ++ code? Can I assume that the common lambda is implemented using the templated operator () function, or is it compiler specific?
template <typename Functor, typename... AllArgs, typename... ProvidedArgs> void findArgTypes(void(Functor::*)(AllArgs...) const, Functor, ProvidedArgs...) { // AllArgs == int, float // ProvidedArgs == int } template <typename Func, typename... ProvidedArgs> void connect(Func func, ProvidedArgs... providedArgs) { findArgTypes(&Func::template operator()<ProvidedArgs...>, func, providedArgs...); } int main() { int tmp = 0; connect([&](auto, float){ ++tmp; }, 0); }
The error that gcc gives is this:
main.cpp: In instantiation of 'void connect(Func, ProvidedArgs ...) [with Func = main()::<lambda(auto:1, float)>; ProvidedArgs = {int}]': main.cpp:16:33: required from here main.cpp:11:17: error: no matches converting function 'operator()' to type 'void (struct main()::<lambda(auto:1, float)>::*)() const' findArgTypes(&Func::template operator()<ProvidedArgs...>, func, providedArgs...); ~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ main.cpp:16:27: note: candidate is: template<class auto:1> main()::<lambda(auto:1, float)> connect([](auto, float){}, 0); ^
Removing const in findArgTypes gives the same result.
Using the following code works with both compilers:
struct Foo { template <typename T> void operator()(T, float) const {} }; int main() { Foo f; connect(f, 0); }