Reputation: 22946
#include <iostream>
#include <vector>
using namespace std;
template <typename nameOfTheVariableTypeA,
typename nameOfTheVariableTypeB> nameOfTheVariableTypeB functionX
(nameOfTheVariableTypeA argA,
(nameOfTheVariableTypeB argB)
{
nameOfTheVariableTypeA tempArgA;
nameOfTheVariableTypeB tempArgB;
argA.push_back(22);
tempArgA = argA;
cout << "\ntempArgA: " << tempArgA[0] << "\n";
tempArgB = argB;
cout << "\ntempArgB: " << tempArgB << "\n";
return tempArgB;
}
int main ()
{
functionX (12, 12.4567);
vector <int> f;
functionX (f, 12.4567);
return 0;
}
From a template book:
An attempt to instantiate a template for a type that doesn't support all the operations used within it will result in a compile-time error.
The error I received for the above code is:
error: request for member ‘push_back’ in ‘argA’, which is of non-class type ‘int’
error: subscripted value is neither array nor pointer
What's the point that I am missing?
Upvotes: 1
Views: 190
Reputation: 6901
A complete code of yours with template specialization :) . As said by other's there is no push_back function for "int" and therefore you need specialized implementation for that.
template < typename nameOfTheVariableTypeA, typename nameOfTheVariableTypeB > nameOfTheVariableTypeB functionX (nameOfTheVariableTypeA argA,nameOfTheVariableTypeB argB) { nameOfTheVariableTypeA tempArgA; nameOfTheVariableTypeB tempArgB; argA.push_back(22); tempArgA = argA; cout << "\ntempArgA: " << tempArgA[0] << "\n"; /*tempArgB = argB; cout << "\ntempArgB: " << tempArgB << "\n";*/ return tempArgB; } template < > float functionX < int,float > (int argA,float argB){ int tempArgA; int tempArgB; tempArgA = argA; cout << "\ntempArgA: " << tempArgA << "\n"; return tempArgB; } int main () { functionX < int,float >(12, 12.4567); vector < int > f; functionX < vector < int > , float > (f, 12.4567); return 0; }
Upvotes: 1
Reputation: 52217
First off, there's a superfluous parenthesis:
template <typename nameOfTheVariableTypeA,
typename nameOfTheVariableTypeB> nameOfTheVariableTypeB functionX
(nameOfTheVariableTypeA argA,
/*(*/nameOfTheVariableTypeB argB)
// Note: extra parenthesis not needed here -----^
{
Assuming that's just a typo, let's take a look the first call to functionX()
:
functionX(12, 12.4567);
Now, template functions require that all template parameters be specified before you can call them. But in certain cases the compiler can deduce the required type for nameOfTheVariableTypeA
and nameOfTheVariableTypeB
for the function call to work.
In this case, 12
is an integer literal, so it has type int
. 12.4567
is a floating-point literal, so it has type double
. Thus, within functionX()
, nameOfTheVariableTypeA
is of type int
and nameOfTheVariableTypeB
is of type double
.
Now that all the template parameters have been specified (in this case, deduced), the compiler can instantiate the template function. That is, the compiler creates a function that looks like this:
// Hypothetical function generated by the compiler
double functionX_int_double(int argA, double argB)
{
int tempArgA;
double tempArgB;
// ...
It's as though the compiler simply substituted nameOfTheVariableTypeA
and nameOfTheVariableTypeB
with the deduced types. Clearly, the argument argA
and variable tempArgA
has type int
. You get the first error because int
doesn't have a class member function called push_back()
. It's the same reason why this won't work:
int i = 20;
i.push_back(22);
You also get the second error because the subscript operator []
is not defined for int
s. Again, it's the same reason why this won't work:
int j = 21;
cout << j[0];
Note that this kind of information can be gleaned from the compiler errors themselves. Make sure you read them!
Upvotes: 3
Reputation: 3909
The call
functionX (12, 12.4567);
instantiantes a function with (int, double)
parameters. The int argA
does neither have a push_back()
method nor an array index operator. So you cannot use tempArgA[0]
also.
Upvotes: 1
Reputation: 7015
In your first call to functionX
:
functionX (12, 12.4567);
The type nameOfTheVariableTypeA
within your template will be inferred as int
. Obviously the int
type doesn't support push_back()
or operator[]
.
Upvotes: 1