A follow up question regarding Is it possible to figure out the parameter type and return type of a lambda?. I tested the code and it works fine for me but only when I call it from main()
, when I call the code from Do
the code does not compile, please let me know if you can uncomment the lines in Do
function and compile the code
#include <tuple>
#include <iostream>
#include <typeinfo>
#include <cxxabi.h>
#include <memory>
template <class T>
std::string GetTypeName()
{
// http://stackoverflow.com/questions/23266391/find-out-the-type-of-auto/23266701#23266701
std::unique_ptr<char, void(*)(void*)> name{abi::__cxa_demangle(typeid(T).name(), 0, 0, nullptr), std::free};
return name.get();
}
template <typename T>
struct function_traits
: public function_traits<decltype(&T::operator())>
{};
template <typename ClassType, typename ReturnType, typename... Args>
struct function_traits<ReturnType(ClassType::*)(Args...) const>
{
enum { arity = sizeof...(Args) };
typedef ReturnType result_type;
template <size_t i>
struct arg
{
typedef typename std::tuple_element<i, std::tuple<Args...>>::type type;
};
};
template <typename FuncType>
void Do(FuncType func)
{
typedef function_traits<decltype(func)> traits;
//typename traits::arg<1>::type x = 0;
std::cout << GetTypeName<traits>() << std::endl;
//std::cout << GetTypeName<traits::arg<1>::type>() << std::endl;
}
int main()
{
auto func = [] (int x, float y, double z) -> void { };
Do(func);
typedef function_traits<decltype(func)> traits;
traits::arg<1>::type x = 0;
std::cout << GetTypeName<traits>() << std::endl;
std::cout << GetTypeName<traits::arg<1>::type>() << std::endl;
return 0;
}
The compilation error is
test.cpp: In function ‘void Do(FuncType)’:
test.cpp:37:20: error: non-template ‘arg’ used as template
typename traits::arg<1>::type x = 0;
^
test.cpp:37:20: note: use ‘traits::template arg’ to indicate that it is a template
test.cpp:37:20: error: declaration does not declare anything [-fpermissive]
I use g++ (GCC) 5.3.1 20160406 (Red Hat 5.3.1-6)
, the compilation command is g++ -std=c++11 test.cpp -o test