About the instantiation of a template class

  • Thread starter =?gb2312?B?wfXquw==?=
  • Start date
?

=?gb2312?B?wfXquw==?=

Hi, folks,
I'm running into a question as below:

template<typename T>
class A {
private:
T _a;
public:
A(T t): _a(t) {
}
};

template<typename T>
void operator+(A<T> lhs, A<T> rhs) {
}

int main() {
A<int> obj(5);
int t = 5;
obj + t;
}

When I try to compile the code above under MSVC8, I got the following
errors:

1. error C2784: 'void operator +(A<T>,A<T>)' : could not deduce
template argument for 'A<T>' from 'int'

2. error C2676: binary '+' : 'A<T>' does not define this operator or a
conversion to a type acceptable to the predefined operator
with
[
T=int
]

Any informative reply will be appreciated, thanks in advance.

Best regards,
Liu Hao
 
A

Adam Nielsen

Hi Liu Hao,
void operator+(A<T> lhs, A<T> rhs) {

This function takes two objects of the A class.

But here you're calling operator+ with one A object and one int.
1. error C2784: 'void operator +(A<T>,A<T>)' : could not deduce
template argument for 'A<T>' from 'int'

The compiler is complaining that it doesn't know how to convert an int
into an A<something> object.

If you used two A objects it would work:

A<int> obj(5);
A<int> obj2(5);
obj + obj2;

You could also rewrite your + operator so that the object doesn't need
to be an instance of A<something>:

void operator+(A<T> lhs, T rhs)

Or alternatively it may be possible to define an operator that allows an
int to be converted into an A<int> - sorry, I'm not sure of the exact
syntax. (I would've thought the constructor would be called implicitly
though - perhaps someone can enlighten us.)

Cheers,
Adam.
 
G

Guest

Hi Liu Hao,


This function takes two objects of the A class.


But here you're calling operator+ with one A object and one int.


The compiler is complaining that it doesn't know how to convert an int
into an A<something> object.

If you used two A objects it would work:

A<int> obj(5);
A<int> obj2(5);
obj + obj2;

You could also rewrite your + operator so that the object doesn't need
to be an instance of A<something>:

void operator+(A<T> lhs, T rhs)

Or alternatively it may be possible to define an operator that allows an
int to be converted into an A<int> - sorry, I'm not sure of the exact
syntax. (I would've thought the constructor would be called implicitly
though - perhaps someone can enlighten us.)

Cheers,
Adam.
 
J

James Kanze

This function takes two objects of the A class.

This is not a function, but a template. It only becomes a
function when instantiated.
But here you're calling operator+ with one A object and one int.

Here, you're asking the compiler to deduce the types for the
above template, and instantiate it using the deduced types.
The compiler is complaining that it doesn't know how to convert an int
into an A<something> object.

No. The compiler knows how to convert an int into an A<int>
object, which is what is wanted. The problem here is that the
rules for type deduction do not allow the compiler to deduce the
arguments for the operator+ template, so it cannot instantiate
the function.
If you used two A objects it would work:
A<int> obj(5);
A<int> obj2(5);
obj + obj2;
You could also rewrite your + operator so that the object
doesn't need to be an instance of A<something>:
void operator+(A<T> lhs, T rhs)
Or alternatively it may be possible to define an operator that
allows an int to be converted into an A<int> - sorry, I'm not
sure of the exact syntax. (I would've thought the constructor
would be called implicitly though - perhaps someone can
enlighten us.)

The usual solution here would be something along the lines of:

template< typename T >
class A
: public Operators< A< T > >
, public MixedOperators< A< T >, T >
{
public:
// ...
A& operator+=( A const& other ) ;
} ;

with the usual definitions for Operators and MixedOperators:

template< typename T >
class Operators
{
public:
friend T operator+( T const& lhs, T const& rhs )
{
T result( lhs ) ;
result += rhs ;
return result ;
}
// And so on for the other operators...
} ;

template< typename T1, typename T2 >
class MixedOperators
{
public:
friend T1 operator+( T1 const& lhs, T2 const& rhs )
{
T1 result( lhs ) ;
result += rhs ; // Note that here, template
// type deduction isn't needed,
// so the compiler will find
// any necessary conversions.
return result ;
}
// And so on for the other operators...
friend T1 operator+( T2 const& lhs, T1 const& rhs )
{
T1 result( rhs ) ;
result += lhs ;
return result ;
}
// And so on for the other commutative operators...
} ;

(Note that in this solution, there are no function
templates:).)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top