471,049 Members | 1,869 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,049 software developers and data experts.

About the instantiation of a template class

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<Tlhs, A<Trhs) {
}

int main() {
A<intobj(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

Oct 12 '07 #1
3 1446
Hi Liu Hao,
void operator+(A<Tlhs, A<Trhs) {
This function takes two objects of the A class.
obj + t;
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<somethingobject.

If you used two A objects it would work:

A<intobj(5);
A<intobj2(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<Tlhs, 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.
Oct 12 '07 #2
On 10 12 , 10 31 , Adam Nielsen <adam.niel...@remove.this.uq.edu.au>
wrote:
Hi Liu Hao,
void operator+(A<Tlhs, A<Trhs) {

This function takes two objects of the A class.
obj + t;

But here you're calling operator+ with one A object and one int.
>
>I think here the compiler is invoking the constructor A(int t) of class A<int>, thus got an temporary A<intobject.
>
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<somethingobject.

If you used two A objects it would work:

A<intobj(5);
A<intobj2(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<Tlhs, 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.

Oct 12 '07 #3
On Oct 12, 4:31 am, Adam Nielsen <adam.niel...@remove.this.uq.edu.au>
wrote:
void operator+(A<Tlhs, A<Trhs) {
This function takes two objects of the A class.
This is not a function, but a template. It only becomes a
function when instantiated.
obj + t;
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.
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<somethingobject.
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<intobj(5);
A<intobj2(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<Tlhs, 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:-).)

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Oct 12 '07 #4

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

5 posts views Thread by Tony Johansson | last post: by
12 posts views Thread by mlimber | last post: by
3 posts views Thread by Steven T. Hatton | last post: by
5 posts views Thread by Wayne Shu | last post: by
reply views Thread by greek_bill | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.