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
?
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 if
s 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With