template code returntype overload not compiling. whats wrong
I am trying the following code to overload a simple function to work for multiple types. However, it fails to compile. Can some one please tell me whats wrong and how to fix this?
typedef struct str1_type
{
int f1;
int f2;
} STR1;
typedef struct str2_type
{
开发者_Go百科 char f1[100];
char f2[100];
}STR2;
template <typename T1, typename T2>
T2 getFieldOffset(const T1& t, int i);
int main() {
STR1 str1;
STR2 str2;
int i = getFieldOffset(str1,0);
const char* test = getFieldOffset(str2,0);
}
template <typename T1, typename T2>
T2 getFieldOffset(const T1& t, int i)
{
switch (i) {
case 0:
return t.f1;
case 1:
return t.f2;
default:
{
cout << "Invalid index passed: i" << i << endl;
return null;
}
}
}
Here is the error message:
test2.cpp: In function 'int main()':
test2.cpp:73: error: no matching function for call to 'getFieldOffset(STR1&, int)' test2.cpp:75: error: no matching function for call to 'getFieldOffset(STR2&, int)'test2.cpp: In function 'T2 getFieldOffset(const T1&, int)':
test2.cpp:90: error: 'null' was not declared in this scope
template <typename T1, typename T2>
T2 getFieldOffset(const T1& t, int i);
Only template argument T1
can be deduced from the arguments, so you have to explicitly provide the template argument T2
in the template argument list when you make the call.
However, if you use the function template as written, you have to provide arguments for both template parameters. You should swap the positions of T1
and T2
in the template parameter list so that you only have to specify T2
:
template <typename T2, typename T1>
T2 getFieldOffset(const T1& t, int i);
Or, with better names for the template parameters:
template <typename TReturn, typename T>
TReturn getFieldOffset(const T& t, int i);
Now you can call this as:
getFieldOffset<ReturnType>(str1,0);
The compiler cannot deduce return types. One reason is because getFIeldOffset
might return a value that isn't an int
, but is convertible to int
. You must specify when the return type is:
getFieldOffset<STR2,int>(str2,0);
Looks like you should write NULL instead of null and all of it will work fine.
In function 'T2 getFieldOffset(const T1&, int)': test2.cpp:90: error: 'null' was not declared in this scope
The problem is in template instantiation, compiler could not instantiate template because of incorrect 'null', so he doesn't look at ability to use your template as candidate for your function calling.
int i = getFieldOffset(str1,0);
const char* test = getFieldOffset(str2,0);
getFieldOffset
is a function template which takes two type argument. But in the above code, you didn't provide type argument. You want the compiler to deduce them. But the compiler can deduce only the function parameter type, not the return type. Hence the error.
You've to provide both type arguments:
int i = getFieldOffset<STR1, int>(str1,0);
const char* test = getFieldOffset<STR2, char*>(str2,0);
However if you reverse the order of types in the function template as
template <typename T1, typename T2>
T1 getFieldOffset(const T2& t, int i); //T1 (i.e 1st type) becomes returnType!!
Then you can provide only one type, the return type, when calling the function; the other type can be deduced from the function argument:
int i = getFieldOffset<int>(str1,0);
const char* test = getFieldOffset<char*>(str2,0);
精彩评论