Passing any function as template parameter

前端 未结 3 1703
天涯浪人
天涯浪人 2021-01-31 03:10

I want to pass a function value as a template parameter to a function. Currently the best I managed to do is :

template< typename F, F f >         


        
相关标签:
3条回答
  • 2021-01-31 03:27

    It's now possible in C++17 with template<auto>:

    template<auto Func>
    struct FuncWrapper final
    {
        template<typename... Args>
        auto operator()(Args &&... args) const
        {
            return Func(std::forward<Args>(args)...);
        }
    };
    
    int add(int a, int b)
    {
        return a + b;
    }
    
    int main()
    {
        FuncWrapper<add> wrapper;
        return wrapper(12, 34);
    }
    

    Demo: https://godbolt.org/g/B7W56t

    You can use #ifdef __cpp_nontype_template_parameter_auto to detect compiler support for this in your code.

    If you are able to use C++20 and you want better error messages, you can also use concepts:

    template<typename T>
    concept CanAddTwoNumbers = std::is_invocable_r_v<int, T, int, int>;
    
    template<auto Func>
        requires CanAddTwoNumbers<decltype(Func)>
    struct AddTwoNumbersWrapper final
    {
        auto operator()(int a, int b) const
        -> int
        {
            return std::invoke(Func, a, b);
        }
    };
    
    int add(int a, int b)
    {
        return a + b;
    }
    
    int main()
    {
        AddTwoNumbersWrapper<add> wrapper;
        return wrapper(12, 34);
        AddTwoNumbersWrapper<123> bad; //error: constraint failure
    }
    

    Demo: https://gcc.godbolt.org/z/ai3WGH

    0 讨论(0)
  • 2021-01-31 03:40

    I believe shortening this is currently impossible. A year ago, the C++ committee looked at http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3601.html to fix this, and they encouraged the authors to pursue it further after C++14 was released.

    0 讨论(0)
  • 2021-01-31 03:40

    You need to make a typedef for whatever function type you want to pass as a pointer, like this:

    typedef int (*MyFunctionType)(int);
    
    template <typename FunctionTypedef, typename ReturnType, typename ParameterType>
    ReturnType callFunction(FunctionTypedef functionPointer, ParameterType i)
    {
      static MyFunctionType myFunctionPointer = functionPointer;
      return (*functionPointer)(i);
    }
    int myFunction(int i)
    {
    }
    
    
    int main()
    {
      int i = 7;
      MyFunctionType myFunctionPointer = myFunction;
      return callFunction<MyFunctionType, int, int>(myFunctionPointer, i);
    }
    

    Edit: If you want to store these arbitrarily typed function pointers, then make a base class with a virtual "call function" function, and a templated derived class that implements this function.

    0 讨论(0)
提交回复
热议问题