Search code examples
c++templatesfunctoroverloading

C++ distinguish Functor and Value template argument


In general I'm having some trouble understanding functors, as I'm fairly new with template programming.

What I'm trying to accomplish here is the following, I'm trying to have a function that takes a Functor and an overloaded function that takes a value.

ideally:

template<typename ValueType>
int function(ValueType v)
{
    v + 1;
    ...
}

template<typename Functor>
int function(Functor f)
{
    f();
    ...
}

I would be fine taking a performance hit with something like taking an std::function as parameter, but I especially want to be able to take a lambda as parameter.

EDIT

What I'm trying to achieve is to allow a construct I'm building to have lazy evaluation when necessary:

construct.option(1)
construct.option([](){ return 5;})
construct.value()

With the construct choosing which argument's value to get when option is called. (likely with an extra argument determining whether that option is chosen)

To be clear, as soon as this option call is done, it knows whether to evaluate the expression or not.

Also if the argument overloads the () operator, I want to call it, regardless of it overloads the + 1 too.


Solution

  • Yes, you can do that using SFINAE:

    // overload taking functor f(int)
    template<typename Func>
    std::result_of_t<Func(int)>   // or std::invoke_result_t<> (C++17)
    function(Func const&func)
    {
        return func(0);
    }
    
    // overload taking value of builtin arithmetic type
    template<typename ValueType>
    enable_if_t<std::is_arithmetic<ValueType>::value, ValueType>
    function(Value const&val)
    {
        return val;
    }