Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can we have a function with multiple return types? (in C++11 and above)

I am trying to write a generic function which takes input as uint8, uint16, uint32, uint64, .... and return the maximum value with the datatype of largest element?

For example:

template < typename T, typename X>
auto Max_Number(T valueA, X valueB)
{
    if (valueA > valueB)
        return valueA;
    else
        return valueB;
}

P.S: this example assumes the largest element is of the largest datatype.

like image 672
Kiran ND Avatar asked Sep 16 '19 06:09

Kiran ND


People also ask

Can a function have multiple return statements in C?

In C or C++, we cannot return multiple values from a function directly.

Can functions have multiple returns?

As you already know a function can return a single variable, but it can also return multiple variables.

Can a function return different types?

If the return type is always derived from a specific class: You can use templates, if you know what type to return before you call the function. But you can't have a function, which internally decide to return some type.

Can a function have more than one return type C++?

A C++ function can return only one value. However, you can return multiple values by wrapping them in a class or struct.


3 Answers

The return type must be determined at compile-time. You might use std::common_type (since C++11):

For arithmetic types not subject to promotion, the common type may be viewed as the type of the (possibly mixed-mode) arithmetic expression such as T0() + T1() + ... + Tn().

template < typename T, typename X>
typename std::common_type<T, X>::type Max_Number ( T valueA, X valueB ) {
    ...
}

Or use std::conditional (since C++11) to declare the return type as the big one (whose sizeof is greater).

template < typename T, typename X>
typename std::conditional<sizeof(T) >= sizeof(X), T, X>::type Max_Number ( T valueA, X valueB ) {
    ...
}

Note that for this case, if T and X have the same size, T will always be used as the return type. If you want to control it more precisely, you can use some traits to specify the exact type.

like image 109
songyuanyao Avatar answered Oct 14 '22 03:10

songyuanyao


Here is an example solution with std:: variant

template < typename T, typename X> 
std::variant<T, X>  Max_Number ( T valueA, X valueB )
{
    std::variant<T, X> res;
    if ( valueA > valueB ) 
       res = valueA; 
    else 
       res = valueB; 
    return res;
}
like image 29
Oblivion Avatar answered Oct 14 '22 03:10

Oblivion


The Trailing return with a conditional operator is another way to go, which is available since c++11.

(See online live)

template <typename T, typename X>
constexpr auto Max_Number(T valueA, X valueB)-> decltype(valueA > valueB ? valueA : valueB)
{
    return valueA > valueB ? valueA : valueB;
}

See some advantages of using trailing return type here: Advantage of using trailing return type in C++11 functions

like image 33
JeJo Avatar answered Oct 14 '22 04:10

JeJo