Search code examples
c++templatesc++11lambdastd-function

Default function that just returns the passed value?


As a lazy developer, I like to use this trick to specify a default function:

template <class Type, unsigned int Size, class Function = std::less<Type> >
void arrange(std::array<Type, Size> &x, Function&& f = Function())
{
    std::sort(std::begin(x), std::end(x), f);
}

But I have a problem in a very particular case, which is the following:

template <class Type, unsigned int Size, class Function = /*SOMETHING 1*/>
void index(std::array<Type, Size> &x, Function&& f = /*SOMETHING 2*/)
{
    for (unsigned int i = 0; i < Size; ++i) {
        x[i] = f(i);
    }
}

In this case, I would like the default function to be the equivalent of: [](const unsigned int i){return i;} (a function that just returns the passed value).

In order to do that, what do I have to write instead of /*SOMETHING 1*/ and /*SOMETHING 2*/?


Solution

  • There is no standard functor that does this, but it is easy enough to write (though the exact form is up for some dispute):

    struct identity {
        template<typename U>
        constexpr auto operator()(U&& v) const noexcept
            -> decltype(std::forward<U>(v))
        {
            return std::forward<U>(v);
        }
    };
    

    This can be used as follows:

    template <class Type, std::size_t Size, class Function = identity>
    void index(std::array<Type, Size> &x, Function&& f = Function())
    {
        for (unsigned int i = 0; i < Size; ++i) {
            x[i] = f(i);
        }
    }