Home > OS >  Template parameter deduction based on supplied lambda
Template parameter deduction based on supplied lambda

Time:08-26

I am exploring template parameter deduction in C and am currently facing the problem to deduce the parameter to a lambda and the return type of the method it's passed to as a parameter at the same time. I think it should be possible, since all the types are known at compile time, but I fail to find the solution.

Some my question is:

Is it possible to change the template struct Action in such a way that the last line containing result3 =... will compile? What changes a necessary

Compiler: gcc 7.5 and gcc 12.1

Thank you very much for your help!



template <typename Function>
struct function_traits : public function_traits<decltype(&Function::operator())> {};

template <typename ClassType, typename ReturnType, typename... Args>
struct function_traits<ReturnType(ClassType::*)(Args...) const> {
  typedef const std::function<ReturnType(Args...)> function;
};

template <typename Function>
typename function_traits<Function>::function to_function (Function& lambda) {
  return static_cast<typename function_traits<Function>::function>(lambda);
}
  

template<typename A>
struct Action{
  A a;
  Action(A const& a_) : a(a_){}

  //allows action<type>(auto a){...})
  template<typename B>
  Action<B> action(std::function<B(A const&)> const& f) const{
    return Action<B>(f(a));
  }

  //allows action([](A a){....})
  template<typename CallableT>
  auto action(CallableT const& f) -> decltype(auto){
    auto g = to_function(f);
    using TargetType = decltype(g(a));
    return action<TargetType>(g);
  }

  //How to combine both????
};

void useAction(){
  Action<int> a(10);
  //both is possible  
  auto result1 = a.action([](int a){return static_cast<double>(a);});
  auto result2 = a.action<double>([](auto a){return static_cast<double>(a);});

  //The following does not compile. Can it be made to compile?
  auto result3 = a.action([](auto a){return static_cast<double>(a);});
}  


CodePudding user response:

Function::operator() may be a template, in which case &Function::operator() will fail.

Function::operator() may be overloaded, in which case &Function::operator() will also fail.

A lambda with an auto parameter has a template operator().

struct function_traits doesn't know and doesn't care about Action<A>. All it has is your lambda.

Get rid of to_function and associated machinery, you don't need them.

//    auto g = to_function(f); <--- not needed
using TargetType = decltype(f(a));
std::function<TargetType(A const&)> g = f;
  •  Tags:  
  • c
  • Related