Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Question about operator overloads and class template members

0 views
Skip to first unread message

alep...@gmail.com

unread,
Jan 2, 2009, 3:03:58 PM1/2/09
to
An error message from gcc leads me to this question:

Can an operator be overloaded for a class template as both a member
function and a friend template function?

In the following code, I declare operator+ to be both a member
function (for int) and a friend template function (for C<T>):

////////////////////////////////////////////////////////////
// Forward declarations
template<typename T> struct C;
template<typename T> C<T> operator+(C<T> self, C<T> that);

// Template with operator+ as both a member and friend
template<typename T>
struct C {
C<T> operator+(int) { return C<T>(); }
friend C<T> operator+ <>(C<T> self, C<T> that);
// Above line gives an error: "declaration of operator+ as non-
function"
};

template<typename T>
C<T> operator+(C<T> self, C<T> that) { return C<T>(); }


int main() {
C<char> a, b, c=a+b, d=a+0;
}
////////////////////////////////////////////////////////////

Is this supposed to be legal? Maybe it's a parse error in gcc?
(Oddly enough, if I put the friend declaration first, I don't get the
error message.)

Cédric Baudry

unread,
Jan 2, 2009, 5:09:15 PM1/2/09
to

It looks Barely legal !

I think I spotted 2 errors in one line


friend C<T> operator+ <>(C<T> self, C<T> that);

You need to remove the <>, well it reminds me of the diamond operator
in Perl. I don't think gcc is much pleased with it.

Anyway, I take away the diamond, add template<typename T> before
friend
and poof, VC++ 2008 built it.

It even executes flawlessly.

However it's gona need real tests to see if it really works.

Tell me how it goes. Cheers.

---

#ifndef FRIEND_OP
#define FRIEND_OP

// Forward declarations
template<typename T> struct C;
template<typename T> C<T> operator+(C<T> self, C<T> that);


// Template with operator+ as both a member and friend
template<typename T>
struct C {

C<T> operator+(int i) { return C<T>(); }
template<typename T> friend C<T> operator+ (C<T> self, C<T>
that);
};


template<typename T>
C<T> operator + ( C<T> self, C<T> that) { return C<T>(); }

#endif

---

#include <stdio.h>
#include <iostream>

#include "friend_operator.h"

int main() {
C<char> a, b, c=a+b, d=a+0;

system("pause");
}

alep...@gmail.com

unread,
Jan 2, 2009, 5:38:36 PM1/2/09
to
On Jan 2, 3:09 pm, Cédric Baudry <mr.cedric.bau...@gmail.com> wrote:
> Anyway, I take away the diamond, add template<typename T> before
> friend
> and poof, VC++ 2008 built it.

This does something different from what I desire, though. This makes
every C<T> grant friendship to every operator+(C<U>, C<U>). (Thus,
C<string> will grant friendship to operator+(C<int>, C<int>).) I only
want to grant friendship to the matching operator+ function.

> I think I spotted 2 errors in one line
> friend C<T> operator+ <>(C<T> self, C<T> that);
>
> You need to remove the <>, well it reminds me of the diamond operator
> in Perl. I don't think gcc is much pleased with it.

I believe the diamond '<>' is there to indicate that it is a function
template. When I remove the diamond, gcc warns that the friend
declaration is declaring a non-template function (which I don't want
to do--the function is a template). Gcc then proceeds to tell me that
if that's not what I intend, I should add the diamond.

Cédric Baudry

unread,
Jan 2, 2009, 8:34:32 PM1/2/09
to

It seems Visual C++ 8 doesn't want a <>. I can't compile the source. :
(

The diamond '<>' seems to be non portable.

0 new messages