something wrong with template instantiation mechanics

Oleg Krivosheev kriol@fnal.gov
Fri Oct 10 17:21:00 GMT 1997


hi,

On Fri, 10 Oct 1997, Jason Merrill wrote:

> >>>>> Oleg Krivosheev <kriol@fnal.gov> writes:
> 
> > after reading CD2 and thinking a bit i still
> > believe this is a bug:
> 
> >   14.8.3  Overload resolution                                [temp.over]
> 
> > ..
> >   For each function template, if the  argument
> >   deduction succeeds, the deduced template-arguments are used to instan-
> >   tiate a single function template specialization which is added to  the
> >   candidate  functions set to be used in overload resolution.
> > ..
> 
> > well, lloks like egcs deduces templates argument right,
> 
> Yes.
> 
> > then it properly did everload resolution and
> > choose template version of abs
> 
> No.  It chose the non-template abs declared by the line
> 
>     friend numT            abs( const TVector3D<numT>& );      
> 

hmm...
ok, reading again CD2:

  14.5.3  Friends                                          [temp.friend]

1 A friend function of a class template can be a function template or an
  ordinary (non-template) function.  [Example:
          template<class T> class task {
              // ...
              friend void next_time();
              friend task<T>* preempt(task<T>*);
              friend task* prmt(task*);           // task is task<T>
              friend class task<int>;
              // ...
          };
  Here,  next_time()  and  task<int> become friends of all task classes,
  and each task has appropriately typed functions preempt()  and  prmt()
  as  friends.   The preempt functions might be defined as a template as
  follows
          template<class T> task<T>* preempt(task<T>* t) { /* ... */ }
   --end example]


it looks for me that i'v declared/defined 
abs and op+ in exactly the same manner as proposed in CD2.
It worked just fine with egcs-2.90.10, so it's regression, IMO
Just in case, i've enclosed below very small test case for op+:

template <class T> class X {
  public:
    X( T );
    X( const X<T>& );
    ~X();
    friend X<T> operator+( const X<T>&, const X<T>& );
  private:
    T t_;
};

template <class T>
X<T>::
X( T t ):
  t_(t) {
}

template <class T>
X<T>::
X( const X<T>& x ):
  t_(x.t_) {
}

template <class T>
X<T>::
~X() {
}

template <class T> X<T>
operator+( const X<T>& a, const X<T>& b ) {
  return X<T>( a.t_ + b.t_ );
}

main( void ) {
}

void
dummy( void ) {
  X<int> x( 1 );
  X<int> y( 2 );

  x = x+y;
}





More information about the Gcc mailing list