template expansion and operator overloading

Tim Rowley tor@cs.brown.edu
Fri Oct 16 09:51:00 GMT 1998


Bug:

Template expansion with operator overloading appears to confuse
egcs and make it try to pick the wrong operator.  The included
source is a minimal example and shows two of these problems (one
is currently commented out).  The program comments document what
behavior we expect and what egcs exhibits.  The test program
compiles without problems with the Sun and SGI native compilers.

Version of egcs (g++ -v):

Reading specs from /u/tor/gfx/lib/gcc-lib/sparc-sun-solaris2.6/egcs-2.92.13/specs
gcc version egcs-2.92.13 19981005 (gcc2 ss-980609 experimental)

Source which exhibits bug:

       Attached below.

Command line:

	g++ -c egtemplate.C

Machine type:

	SunOS boojum 5.6 Generic_105181-07 sun4u sparc SUNW,Ultra-1

Compiler installation:

	 ./configure --prefix=/u/tor/gfx

Modifications to compiler source:

	 None.

Deviations from standard install procedure:

	 None.

--------------------------------------------
/*
   Dies when compiled with:
   g++ -c egtemplate.
*/

class Wline;

// This allows us to define T::operator * and then use 0.5 * T()
// Or at least should...
template <class T>
inline T operator *(double s, const T &p) { return p * s; }

template <class P>
class _point3d
{
    public:
    P  operator  *(double s)        const{ return P();}
}; // class point3d

template <class L, class P>
class _line
{
  public:
    // This should just call P::operator*(double), in this case
    // _point3d::operator *...
    // But instead, egcs gets confused and wants to run operator*(double, T)
/*
egtemplate.C: In method `class Wpt _line<Wline,Wpt>::halve(const class Wline &) const':
egtemplate.C:54:   instantiated from here
egtemplate.C:11: `operator *(double, const double &)' must have an argument of class or enumerated type
*/
//    P  halve(const L &l)   const  { return P() * .5; }
          
    // This should call T::operator *(double, P)
    // Instead, we get:
/*
egtemplate.C: In function `class Wpt operator *<Wpt>(double, const class Wpt &)' :
egtemplate.C:42:   instantiated from `_line<Wline,Wpt>::halve(const Wline &) const'
egtemplate.C:54:   instantiated from here
egtemplate.C:11: `operator *(double, const double &)' must have an argument of class or enumerated type
*/
    P  halve(const L &l)   const  { return 0.5 * P(); }
};  // class _line

class Wpt : public _point3d<Wpt> {
   public :
    Wpt() { }
    Wpt(const Wline &, const Wline &);
};

class Wline : public _line<Wline, Wpt> { };

Wpt::Wpt(const Wline  &a, const Wline &b) {
   (*this) = a.halve(b);
}



More information about the Gcc-bugs mailing list