Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to return different types based on std::is_same check [duplicate]

Tags:

c++

templates

Consider the following code:

template<typename T>
T foo() {
    if (std::is_same<T, int>::value)
        return 5;

    if (std::is_same<T, std::string>::value)
        return std::string("bar");

    throw std::exception();
}

When called with foo<int>(), it throws an error cannot convert ‘std::__cxx11::string {aka std::__cxx11::basic_string<char>}’ to ‘int’ in return.

I know the solution is to use template specialization, but I'm asking whether it is somehow possible to keep the current mechanism with checking the type via std::is_same?

like image 712
Martin Heralecký Avatar asked Jun 05 '18 16:06

Martin Heralecký


1 Answers

Both branches of an if must be valid at compile-time, even if one of them is never executed.

If you have access to C++17, change the ifs to if constexpr:

template<typename T>
T foo() {
    if constexpr (std::is_same<T, int>::value)
        return 5;

    if constexpr (std::is_same<T, std::string>::value)
        return std::string("bar");

    throw std::exception();
}

Before C++17, you will have to emulate this by using template specialisation:

template<typename T>
T foo()
{
    throw std::exception();
}

template <>
int foo<int>() {
    return 5;
}

template <>
std::string foo<std::string>() {
    return "bar";
}

If your real foo does more work than this example and specialising it would lead to code duplication, you can introduce a helper function which will encapsulate only the return/throw statements, and specialise that.

like image 92
Angew is no longer proud of SO Avatar answered Nov 03 '22 00:11

Angew is no longer proud of SO