Reputation: 2568
I have the following function template
template<typename T>
T foo(){
if(std::is_same<T,int>::value){
return 1;
}
if(std::is_same<T,std::string>::value){
return "Hello";
}
}
I want to apply it like this:
int main(){
std::cout << foo<int>() << std::endl; // 1
std::cout << foo<string>() << std::endl; // "Hello"
}
If I try to compile my template the compiler throws the following error:
error: cannot initialize return object of type 'int' with an lvalue of type 'const char [6]'
.
If I remove the second if
statement everything compiles fine and I get the correct output therefore I guess the comparison std::is_same<T,int>::value
works as intended.
It seems like the Compiler detects the type of T
, checks if all return
statements match it and throws the error because an std::string
is not implicitly castable to int
.
Has anyone a solution or another workaround to satisfy my intention?
EDIT
To explain my intention: I am writing a wrapper class for a database cursor class. As these cursors are usually defined it has several member functions like getInt()
or getString()
. My idea was to implement a generic get<T>()
that uses the corresponding cursor member function that depends on T
.
Upvotes: 2
Views: 422
Reputation: 638
Forget the if statements and fully specialize the template function:
template<>
int foo<int>(){
return 1;
}
template<>
std::string foo<std::string>(){
return "Hello";
}
Upvotes: 2
Reputation: 16156
When you reference foo<int>
, the compiler generates a function like the following from your template:
int foo<int>(){
if(true){
return 1;
}
if(false){
return "Hello";
}
}
Above code is ill-typed, because (as the compiler tells you) an int
cannot be initialized with a C string (char const [N]
). Sure, the corresponding return
statement will never be reached, but that's something to be figured out by "dead code elimination", which is merely an optimization.
The solution "now" is shown in Dustin's answer, with C++17 we'll get if constexpr
which is able to discard code paths the way you expected it:
template<typename T>
T foo(){
if constexpr (std::is_same<T,int>::value){
return 1;
}
if constexpr (std::is_same<T,std::string>::value){
return "Hello";
}
}
Upvotes: 1