Search code examples
c++referencec++17return-typeauto

Hint the compiler to return by reference when using auto, without using ->


I have a function that has the return type set to auto. If I want to return something by reference, normally I can simply hint the compiler with -> T&. However in my specific case I have a templated function which has different return paths defined through an if constexpr expression. Something like this:

template<typename T>
auto fn(T& arg)
{
    if constexpr (std::is_same_v<T, int>)
        return;
    else
        return arg;
}

I want to return arg by reference in the second case. Is there a way to hint the compiler as to the type inside the function body? I know that I can do std::ref(arg), but then the returned type is a reference wrapper, so if I do auto& res = fn(arg) it simply fails when I try to use it as an actual reference. Basically I want the vanilla behaviour one would get through -> T&, but for a function that can return various types, so I want to provide the hint within the function body.


Solution

  • Use decltype(auto) instead, which evaluates to the exact type of the expression you're returning:

    template<typename T>
    decltype(auto) fn(T& arg)
    {
        if constexpr (std::is_same_v<T, int>)
            return;
        else
            return arg;
    }
    
    • When calling int i; fn(i);, the return type will be void.

    • When calling float f; fn(f);, the return type will be float&.

    live example on godbolt.org with static_assert evidence