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.)
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");
}
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.
It seems Visual C++ 8 doesn't want a <>. I can't compile the source. :
(
The diamond '<>' seems to be non portable.