Template friend (unary and binary) operators

R

Ruben Campos

Some questions about this code:

template <typename T> class MyTemplate;
template <typename T> MyTemplate <T> operator- (const MyTemplate <T> &
object);
template <typename T> MyTemplate <T> operator- (const MyTemplate <T> &
object1, const MyTemplate <T> & object2);

template <typename T>
class MyTemplate
{
public:
MyTemplate (const T & data = T()) : mData(data) {}
MyTemplate (const MyTemplate <T> & object) : mData(object.mData) {}

MyTemplate <T> & operator= (const MyTemplate <T> & object) { mData =
object.mData; return *this; }

friend MyTemplate <T> operator- <T> (const MyTemplate <T> & object);
MyTemplate <T> & operator-= (const MyTemplate <T> & object) { mData -=
object.mData; return *this; }
friend MyTemplate <T> operator- <T> (const MyTemplate <T> & object1,
const MyTemplate <T> & object2);

private:

T mData;
};

template <typename T> MyTemplate <T> operator- (const MyTemplate <T> &
object) { return MyTemplate <T> (-object.mData); }
template <typename T> MyTemplate <T> operator- (const MyTemplate <T> &
object1, const MyTemplate <T> & object2) { MyTemplate <T> result(object1);
result -= object2; return result; }

int
main
{
MyTemplate <float> object1(1.0f);
MyTemplate <float> object2(-object1);
}

a) Trying to compile this wit MS Visual C++ 7.x returns me some syntax and
unexpected token errors, first, and then some "new definition" errors for
the friend operator-, saying me that it was previously defined as a member.
In fact, unary operator- is defined as a member, and subsequently binary
operator- is defined as a friend function. So, they are considered as the
same function by the compiler? This doesn't make sense for me, because they
have different parameters.

In order to deal with this, I've tried two alternatives: a) changing the
template MyTemplate <T> class for a non-template one, while keeping the
unary member and binary friend operator-, and b) keep MyTemplate <T> as a
template class, while changing member unary operator- for a friend one. In
both cases, these errors don't appear, and the code compiles (and works)
fine. So I know it is a fact which concern templates only. Is possible to
include a unary member operator- and a binary friend operator- in the same
template class?

b) Nothing to do with the previous question, first constructor have a
default parameter "const T & data = T()". When I instantiate MyTemplate
<float> objects through this constructor, both in the stack and in the heap,
mData is initialized to 0.0f value. Is this standard, being always all
built-in types initialized to zero when their default constructor (exists?)
is called (inside a template, for example)? Is this a coincidence, favoured
by the involved memory contents at the construction time? Or is this
compiler-dependent, implemented specifically by (in my case) MS Visual C++
7.x?
 
M

Martin Magnusson

Ruben said:
Some questions about this code:

template <typename T> class MyTemplate;
template <typename T> MyTemplate <T> operator- (const MyTemplate <T> &
object);
template <typename T> MyTemplate <T> operator- (const MyTemplate <T> &
object1, const MyTemplate <T> & object2);

template <typename T>
class MyTemplate
{
public:
MyTemplate (const T & data = T()) : mData(data) {}
MyTemplate (const MyTemplate <T> & object) : mData(object.mData) {}

MyTemplate <T> & operator= (const MyTemplate <T> & object) { mData =
object.mData; return *this; }

friend MyTemplate <T> operator- <T> (const MyTemplate <T> & object);
MyTemplate <T> & operator-= (const MyTemplate <T> & object) { mData -=
object.mData; return *this; }
friend MyTemplate <T> operator- <T> (const MyTemplate <T> & object1,
const MyTemplate <T> & object2);

private:

T mData;
};

template <typename T> MyTemplate <T> operator- (const MyTemplate <T> &
object) { return MyTemplate <T> (-object.mData); }
template <typename T> MyTemplate <T> operator- (const MyTemplate <T> &
object1, const MyTemplate <T> & object2) { MyTemplate <T> result(object1);
result -= object2; return result; }

int
main
{
MyTemplate <float> object1(1.0f);
MyTemplate <float> object2(-object1);
}

a) Trying to compile this wit MS Visual C++ 7.x returns me some syntax and
unexpected token errors, first, and then some "new definition" errors for
the friend operator-, saying me that it was previously defined as a member.

It compiles just fine with gcc 3.3.3 (after adding parantheses after
main), so I suppose that there's nothing wring with the code as such.
b) Nothing to do with the previous question, first constructor have a
default parameter "const T & data = T()". When I instantiate MyTemplate
<float> objects through this constructor, both in the stack and in the heap,
mData is initialized to 0.0f value. Is this standard, being always all
built-in types initialized to zero when their default constructor (exists?)
is called (inside a template, for example)? Is this a coincidence, favoured
by the involved memory contents at the construction time? Or is this
compiler-dependent, implemented specifically by (in my case) MS Visual C++
7.x?

I don't believe the standard says anything about implicitly initializing
variables, so (without reading the standard) I'd say it's
compiler-dependent.

/ martin
 
R

Ruben Campos

Martin Magnusson said:
It compiles just fine with gcc 3.3.3 (after adding parantheses after
main), so I suppose that there's nothing wring with the code as such.

Sorry, it's only a transcription error. It should appear as:

int
main (int argn, char ** argc)

The errors I've described are related with the template, and its friend
functions. They appear with MS Visual C++ 7.1.3088, even when enabling the
Microsoft language extensions (which I don't want to keep enabled).
 
R

Ruben Campos

Sorry. I included the code corresponding to the first compilable variation
code, that with unary operator- as a friend function. So tell me repeat my
first message, now corrected. Sorry, Martin Magnusson, for this (all mine)
mistake.

Some questions about this code:

template <typename T> class MyTemplate;
template <typename T> MyTemplate <T> operator- (const MyTemplate <T> &
object1, const MyTemplate <T> & object2);

template <typename T>
class MyTemplate
{
public:
MyTemplate (const T & data = T()) : mData(data) {}
MyTemplate (const MyTemplate <T> & object) : mData(object.mData) {}

MyTemplate <T> & operator= (const MyTemplate <T> & object) { mData =
object.mData; return *this; }

MyTemplate <T> operator- (const MyTemplate <T> & object) { return
MyTemplate <T> (-mData); }
MyTemplate <T> & operator-= (const MyTemplate <T> & object) { mData -=
object.mData; return *this; }
friend MyTemplate <T> operator- <T> (const MyTemplate <T> & object1,
const MyTemplate <T> & object2);

private:
T mData;
};

template <typename T> MyTemplate <T> operator- (const MyTemplate <T> &
object1, const MyTemplate <T> & object2) { MyTemplate <T> result(object1);
result -= object2; return result; }

int
main (int argn, char ** argc)
{
MyTemplate <float> object1(1.0f);
MyTemplate <float> object2(-object1);
}

a) Trying to compile this wit MS Visual C++ 7.x returns me some syntax and
unexpected token errors, first, and then some "new definition" errors for
the binary friend operator-, saying me that it was previously defined as a
member. In fact, unary operator- is defined as a member, and subsequently
binary operator- is defined as a friend function. So, are they considered
the same function by the compiler? This doesn't make sense for me, because
they have different parameters.

In order to deal with this, I've tried two alternatives: a) changing the
template MyTemplate <T> class for a non-template one, while keeping the
unary member and binary friend operator-, and b) keep MyTemplate <T> as a
template class, while changing member unary operator- for a friend one. In
both cases, these errors don't appear, and the code compiles (and works)
fine. So I know it is a fact which concern templates only. Is possible to
include a unary member operator- and a binary friend operator- in the same
template class?

NOTE: in a real case, I use to include all the implementations in a separate
..cpp file (which, in the case of template classes, is #included in the .h).
For readability, and for short, I included here implementation of member
functions directly inside template class declaration, but I kept the
implementation of the friend function outside, in order to reproduce the
error situation. I've tried this code, however, and it really returns me
errors which I've mentioned.

b) Nothing to do with the previous question, first constructor have a
default parameter "const T & data = T()". When I instantiate MyTemplate
<float> objects through this constructor, both in the stack and in the heap,
mData is initialized to 0.0f value. Is this standard, being always all
built-in types initialized to zero when their default constructor (exists?)
is called (inside a template, for example)? Is this a coincidence, favoured
by the involved memory contents at the construction time? Or is this
compiler-dependent, implemented specifically by (in my case) MS Visual C++
7.x?
 
D

Dan Cernat

Ruben Campos said:
Some questions about this code:
[snip]

int
main main ()
{
MyTemplate <float> object1(1.0f);
MyTemplate <float> object2(-object1);
}

With the fix for main compiles just fine with VC++ 7.1

/dan
 
R

Ruben Campos

Please, see my last (and corrected) message in this thread. Sorry for the
mistake, and thank you for your time.

Dan Cernat said:
Ruben Campos said:
Some questions about this code:
[snip]

int
main main ()
{
MyTemplate <float> object1(1.0f);
MyTemplate <float> object2(-object1);
}

With the fix for main compiles just fine with VC++ 7.1

/dan
 

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,995
Messages
2,570,228
Members
46,818
Latest member
SapanaCarpetStudio

Latest Threads

Top