'How to template by-value returning value and by-const-ref returning const ref

Is there a way to have those two cases as a single template:

// accepts by-value, returns value
int f(bool cond, int a, int b) {
    return cond ? a : b;
}

// accepts by-const-ref, returns const ref
const std::string& f(bool cond, const std::string& a,
                     const std::string& b) {
    return cond ? a : b;
}

Using at least C++11.



Solution 1:[1]

Possible, but call would similar to f<int>(42, 51); (using stuff like boost's call_traits).

A simplified version might be

template <typename T>
struct call_traits
{
    using type = const T&;
};

template <typename T>
using call_traits_t = typename call_traits<T>::type;

template <>
struct call_traits<int>
{
    using type = int;
};

// T is not deducible from call_traits_t<T> (aka call_traits<T>::type)
template <typename T>
call_traits_t<T> f(bool cond, call_traits_t<T> true_value, call_traits_t<T> false_value)
{
    return cond ? true_value : false_value;
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Jarod42