Kiran
Kiran

Reputation: 5526

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
{
    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

Upvotes: 1

Views: 315

Answers (4)

Sarfaraz Nawaz
Sarfaraz Nawaz

Reputation: 361262

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);

Upvotes: 1

James McNellis
James McNellis

Reputation: 354979

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); 

Upvotes: 8

Danil Krivopustov
Danil Krivopustov

Reputation: 232

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.

Upvotes: 2

John Dibling
John Dibling

Reputation: 101446

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);

Upvotes: 4

Related Questions