C++11 does not deduce type when std::function or lambda functions are involved

后端 未结 3 1269
夕颜
夕颜 2020-11-22 08:31

When I define this function,

template
set test(const set& input) {
    return input;
}

I can call it u

3条回答
  •  星月不相逢
    2020-11-22 08:43

    If we have:

    template 
    int myfunc(std::function lambda)
    {
      return lambda(2);
    }
    
    int r = myfunc([](int i) { return i + 1; });
    

    It will not compile. But if you previously declare:

    template 
    static auto getFuncType(Func* func = nullptr, Arg1* arg1 = nullptr) -> decltype((*func)(*arg1));
    
    template 
    int myfunc(Func lambda)
    {
      return myfunc())>(lambda);
    }
    

    You can call your function with a lambda parameter without problem.

    There are 2 new pieces of code here.

    First, we have a function declaration which is only useful to return an old-style function pointer type, based on given template parameters:

    template 
    static auto getFuncType(Func* func = nullptr, Arg1* arg1 = nullptr) -> decltype((*func)(*arg1)) {};
    

    Second, we have a function that takes a template argument to build our expected lambda type calling 'getFuncType':

    template 
    int myfunc(Func lambda)
    {
      return myfunc())>(lambda);
    }
    

    With the correct template parameters, now we can call the real 'myfunc'. Complete code will be:

    template 
    int myfunc(std::function lambda)
    {
      return lambda(2);
    }
    
    template 
    static auto getFuncType(Func* func = nullptr, Arg1* arg1 = nullptr) -> decltype((*func)(*arg1)) {};
    
    template 
    int myfunc(Func lambda)
    {
      return myfunc())>(lambda);
    }
    
    int r = myfunc([](int i) { return i + 1; });
    

    You can declare any overload for 'getFuncType' to match your lambda parameter. For example:

    template 
    static auto getFuncType(Func* func = nullptr, Arg1* arg1 = nullptr, Arg2* arg2 = nullptr) -> decltype((*func)(*arg1, *arg2)) {};
    

提交回复
热议问题