c++/4424: Template operator overloading using member functions and bound friend templates fails (repost of 4423)

grendel@swcp.com grendel@swcp.com
Sun Sep 30 00:19:00 GMT 2001


>Number:         4424
>Category:       c++
>Synopsis:       Template operator overloading using member functions and bound friend templates fails  (repost of 4423)
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    unassigned
>State:          open
>Class:          rejects-legal
>Submitter-Id:   net
>Arrival-Date:   Sun Sep 30 00:16:01 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator:     Bill Reynolds
>Release:        2.96
>Organization:
>Environment:
Linux Redhat 7.0 i686
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/2.96/specs
gcc version 2.96 20000731 (Red Hat Linux 7.1 2.96-85)
>Description:
g++ cannot disambiguate two overloads of operator* if the arguments are templates and the class doing the overloading
uses both member fn overloads and friend template fn overloads.

Following code gives the compile error. This code compiles on 
the Comeau online compiler, and as far as I can tell is 
legal code.

This is a repost of bug 4423. Example code didn't upload.
>How-To-Repeat:
#include <iostream>
using namespace std;

// Fwd decl.
template <class T> class opOne ;

// // Friend function templates.
template <typename TYPE> opOne<TYPE> operator*(const TYPE op2, const opOne<TYPE> &op1)
{
   cout << "opOne friend T*opOne\n";
   opOne<TYPE> foo;
   return foo;
}

template <typename TYPE> opOne<TYPE> operator*(opOne<TYPE> const &op1, const TYPE op2)
{
  cout << "opOne friend opOne*T\n";
  opOne<TYPE> foo;
  return  foo;
}


template <class T> class opOne 
{
  // Herein lies the problem. If we enable the friend decl's below, we
  // get a conflict, saying that we've changed the meaning of the
  // member operator* fn (which appears to be a bug, since the 3
  // different operator* 's take different arguments - the compiler
  // seems to get confused). 
  // Obviously, if i have any protection enabled, this will be a
  // problem.

  // Friend functions. Need to be instantiated before class is.
  friend opOne<T> operator*<T>(opOne<T> const &op1, const T op2);
  friend opOne<T> operator*<T>(const T op2, const opOne<T> &op1);

  // Workaround due to Charlie Fitch (cmf@swcp.com)
  //template <typename X> friend opOne<T> operator*(opOne<T> const &op1, const T op2);
  //template <typename X> friend opOne<T> operator*(const T op2, const opOne<T> &op1);

  // Method
public:
  opOne<T> operator* (const opOne<T> &p) const;


};

 template<typename T> opOne<T> opOne<T>::operator*(const opOne<T> &p) const
 {
   cout << "opOne Method opOne*opOne\n";
   opOne<T> foo;
   return foo;
 }

class opTwo
{
 public:
  friend opTwo  operator *  (const opTwo& x, const opTwo& y);//  */
};


opTwo operator * (const opTwo& x, const opTwo& y)
{
  cout << "opTwo Friend: opTwo*opTwo\n";
  opTwo foo;
  return foo;
}



// First we make instances of the class' friend functions.
template opOne<opTwo> operator*(const opTwo op2, const opOne<opTwo> &op1);
template opOne<opTwo> operator*(const opOne<opTwo> &op1, const opTwo op2);

// Now we can make an instance of the class.
template class opOne<opTwo>;

void main(int argc, char **argv)
{
  opOne<opTwo> foo;
  opTwo bar;
  
  // opTwo*opTwo
  bar*bar;
  
  // opOne*opOne
  foo*foo;
  
  // opOne*opTwo
  foo*bar;
  
  // opTwo*opOne
  bar*foo;
}
>Fix:
See (commented out) workaround in code.
>Release-Note:
>Audit-Trail:
>Unformatted:
----gnatsweb-attachment----
Content-Type: application/octet-stream; name="stuf.cc"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="stuf.cc"

I2luY2x1ZGUgPGlvc3RyZWFtPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKLy8gRndkIGRlY2wuCnRl
bXBsYXRlIDxjbGFzcyBUPiBjbGFzcyBvcE9uZSA7CgovLyAvLyBGcmllbmQgZnVuY3Rpb24gdGVt
cGxhdGVzLgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVFlQRT4gb3BPbmU8VFlQRT4gb3BlcmF0b3IqKGNv
bnN0IFRZUEUgb3AyLCBjb25zdCBvcE9uZTxUWVBFPiAmb3AxKQp7CiAgIGNvdXQgPDwgIm9wT25l
IGZyaWVuZCBUKm9wT25lXG4iOwogICBvcE9uZTxUWVBFPiBmb287CiAgIHJldHVybiBmb287Cn0K
CnRlbXBsYXRlIDx0eXBlbmFtZSBUWVBFPiBvcE9uZTxUWVBFPiBvcGVyYXRvcioob3BPbmU8VFlQ
RT4gY29uc3QgJm9wMSwgY29uc3QgVFlQRSBvcDIpCnsKICBjb3V0IDw8ICJvcE9uZSBmcmllbmQg
b3BPbmUqVFxuIjsKICBvcE9uZTxUWVBFPiBmb287CiAgcmV0dXJuICBmb287Cn0KCgp0ZW1wbGF0
ZSA8Y2xhc3MgVD4gY2xhc3Mgb3BPbmUgCnsKICAvLyBIZXJlaW4gbGllcyB0aGUgcHJvYmxlbS4g
SWYgd2UgZW5hYmxlIHRoZSBmcmllbmQgZGVjbCdzIGJlbG93LCB3ZQogIC8vIGdldCBhIGNvbmZs
aWN0LCBzYXlpbmcgdGhhdCB3ZSd2ZSBjaGFuZ2VkIHRoZSBtZWFuaW5nIG9mIHRoZQogIC8vIG1l
bWJlciBvcGVyYXRvciogZm4gKHdoaWNoIGFwcGVhcnMgdG8gYmUgYSBidWcsIHNpbmNlIHRoZSAz
CiAgLy8gZGlmZmVyZW50IG9wZXJhdG9yKiAncyB0YWtlIGRpZmZlcmVudCBhcmd1bWVudHMgLSB0
aGUgY29tcGlsZXIKICAvLyBzZWVtcyB0byBnZXQgY29uZnVzZWQpLiAKICAvLyBPYnZpb3VzbHks
IGlmIGkgaGF2ZSBhbnkgcHJvdGVjdGlvbiBlbmFibGVkLCB0aGlzIHdpbGwgYmUgYQogIC8vIHBy
b2JsZW0uCgogIC8vIEZyaWVuZCBmdW5jdGlvbnMuIE5lZWQgdG8gYmUgaW5zdGFudGlhdGVkIGJl
Zm9yZSBjbGFzcyBpcy4KICAvL2ZyaWVuZCBvcE9uZTxUPiBvcGVyYXRvcio8VD4ob3BPbmU8VD4g
Y29uc3QgJm9wMSwgY29uc3QgVCBvcDIpOwogIC8vZnJpZW5kIG9wT25lPFQ+IG9wZXJhdG9yKjxU
Pihjb25zdCBUIG9wMiwgY29uc3Qgb3BPbmU8VD4gJm9wMSk7CgogIC8vIFdvcmthcm91bmQgZHVl
IHRvIENoYXJsaWUgRml0Y2ggKGNtZkBzd2NwLmNvbSkKICB0ZW1wbGF0ZSA8dHlwZW5hbWUgWD4g
ZnJpZW5kIG9wT25lPFQ+IG9wZXJhdG9yKihvcE9uZTxUPiBjb25zdCAmb3AxLCBjb25zdCBUIG9w
Mik7CiAgdGVtcGxhdGUgPHR5cGVuYW1lIFg+IGZyaWVuZCBvcE9uZTxUPiBvcGVyYXRvciooY29u
c3QgVCBvcDIsIGNvbnN0IG9wT25lPFQ+ICZvcDEpOwoKICAvLyBNZXRob2QKcHVibGljOgogIG9w
T25lPFQ+IG9wZXJhdG9yKiAoY29uc3Qgb3BPbmU8VD4gJnApIGNvbnN0OwoKCn07CgogdGVtcGxh
dGU8dHlwZW5hbWUgVD4gb3BPbmU8VD4gb3BPbmU8VD46Om9wZXJhdG9yKihjb25zdCBvcE9uZTxU
PiAmcCkgY29uc3QKIHsKICAgY291dCA8PCAib3BPbmUgTWV0aG9kIG9wT25lKm9wT25lXG4iOwog
ICBvcE9uZTxUPiBmb287CiAgIHJldHVybiBmb287CiB9CgpjbGFzcyBvcFR3bwp7CiBwdWJsaWM6
CiAgZnJpZW5kIG9wVHdvICBvcGVyYXRvciAqICAoY29uc3Qgb3BUd28mIHgsIGNvbnN0IG9wVHdv
JiB5KTsvLyAgKi8KfTsKCgpvcFR3byBvcGVyYXRvciAqIChjb25zdCBvcFR3byYgeCwgY29uc3Qg
b3BUd28mIHkpCnsKICBjb3V0IDw8ICJvcFR3byBGcmllbmQ6IG9wVHdvKm9wVHdvXG4iOwogIG9w
VHdvIGZvbzsKICByZXR1cm4gZm9vOwp9CgoKCi8vIEZpcnN0IHdlIG1ha2UgaW5zdGFuY2VzIG9m
IHRoZSBjbGFzcycgZnJpZW5kIGZ1bmN0aW9ucy4KdGVtcGxhdGUgb3BPbmU8b3BUd28+IG9wZXJh
dG9yKihjb25zdCBvcFR3byBvcDIsIGNvbnN0IG9wT25lPG9wVHdvPiAmb3AxKTsKdGVtcGxhdGUg
b3BPbmU8b3BUd28+IG9wZXJhdG9yKihjb25zdCBvcE9uZTxvcFR3bz4gJm9wMSwgY29uc3Qgb3BU
d28gb3AyKTsKCi8vIE5vdyB3ZSBjYW4gbWFrZSBhbiBpbnN0YW5jZSBvZiB0aGUgY2xhc3MuCnRl
bXBsYXRlIGNsYXNzIG9wT25lPG9wVHdvPjsKCnZvaWQgbWFpbihpbnQgYXJnYywgY2hhciAqKmFy
Z3YpCnsKICBvcE9uZTxvcFR3bz4gZm9vOwogIG9wVHdvIGJhcjsKICAKICAvLyBvcFR3bypvcFR3
bwogIGJhcipiYXI7CiAgCiAgLy8gb3BPbmUqb3BPbmUKICBmb28qZm9vOwogIAogIC8vIG9wT25l
Km9wVHdvCiAgZm9vKmJhcjsKICAKICAvLyBvcFR3bypvcE9uZQogIGJhcipmb287Cn0K



More information about the Gcc-bugs mailing list