Topic: Can templated operators ambiguate user-supplied ones?


Author: vandevod@cs.rpi.edu (David Vandevoorde)
Date: 1996/12/06
Raw View
>>>>> "PH" == Pablo Halpern <phalpern@truffle.ma.ultranet.com> writes:
[...]
PH> A related question. If a non-template declaration in the presence
PH> of a template declaration is a real function declaration, then
PH> what happened to the "guiding declarations" of the April 1995 DWP.

They were eliminated in Stockholm.

 Daveed


[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: fwai@armltd.co.uk (Francis Wai)
Date: 1996/11/29
Raw View
lars.farm@ite.mh.se (Lars Farm) writes:

>This is for an exact match. What about inheritance:

>  class base{};
>  class derived : public base {};

>  template<class T> void f( const T& );
>  void f( const base& );

>  void foo() {
>    derived d;
>    f( d );         // which f() is called?
>                    //    void f(const base&) or
>  }                 //    void f<derived>(const derived&)

The compiler should choose "f<derived>(const derived&)". The proposed
DWP is clear about the generation of template functions and its interaction
with overload resolution. It says,

  14.10.3  Overload resolution                               [temp.over]

1 A function template can be overloaded either by (other)  functions  of
  its  name  or by (other) function templates of that same name.  When a
  call to that name is written  (explicitly,  or  implicitly  using  the
  operator  notation),  template  argument  deduction (_temp.deduct_) is
  performed on each function template to find the template argument val-
  ues  (if any) that can be used with that function template to generate
  a function that can be invoked with  the  call  arguments.   For  each
  function  template,  if  the  argument deduction succeeds, the deduced
  template arguments are used to generate a  single  template  function,
  which  is  added to the candidate functions set to be used in overload
  resolution.  If, for a given  function  template,  argument  deduction
  fails, no such function is added to the set of candidate functions for
  that template.  The complete set of candidate functions  includes  all
  the  template  functions  generated  in  this  way and all of the non-
  template overloaded functions of the same name.   The  template  func-
  tions  are  treated like any other functions in the remainder of over-
  load resolution, except as explicitly noted.3)

And in overload resolution, an exact match is always preferred.

--Francis
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Matt Austern <austern@isolde.mti.sgi.com>
Date: 1996/12/04
Raw View
bradds@concentric.net (Bradd W. Szonye) writes:

> >(14.10.5.2). That is, there is no bug in GCC at this point. Unless
> >I misunderstand something, using STL expose all your classes
> >that possess one of the four operators !=, >, <= or >= to
> >possible ambiguation. This is too bad to be true...
>
> It's not all that bad, unless you're "using namespace std" or "using
> std::operator X". Otherwise, the operator templates are only visible within
> namespace std (and the library is careful to define things in terms of
> less<T> or operator<, which it does not define).

Actually, it's even less threatening than this: the draft standard
defines these operators as members of namespace ::std::rel_ops.  (This
is the only namespace nested within namespace std.)  It's unlikely
that you'll ever pick them up unintentionally.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: phalpern@truffle.ma.ultranet.com (Pablo Halpern)
Date: 1996/12/05
Raw View
fwai@armltd.co.uk (Francis Wai) wrote:

>lars.farm@ite.mh.se (Lars Farm) writes:
>
>>This is for an exact match. What about inheritance:
>
>>  class base{};
>>  class derived : public base {};
>
>>  template<class T> void f( const T& );
>>  void f( const base& );
>
>>  void foo() {
>>    derived d;
>>    f( d );         // which f() is called?
>>                    //    void f(const base&) or
>>  }                 //    void f<derived>(const derived&)
>
>The compiler should choose "f<derived>(const derived&)". The proposed
>DWP is clear about the generation of template functions and its interaction
>with overload resolution. It says,
>
[ DWP quote removed ]

Please state which DWP you refer to. Is it the April 1995 or the Sept
1996 DWP. If the latter, then I am confused. The section you mentioned
does not indicate that in the case of an ambiguity (i.e., both the
template and non-template functions are an exact signature match), then
the non-template function is prefered. This contradicts what Alexandre
Oliva said.

A related question. If a non-template declaration in the presence of a
template declaration is a real function declaration, then what happened
to the "guiding declarations" of the April 1995 DWP.  In the April 1995
DWP, the whole interaction between template and non-template functions
with the same name made me queazy. It seemed as though a valid
declaration would suddenly become a guiding declaration if somebody
added a template function in some header file. I hope things have
improved.

-------------------------------------------------------------
Pablo Halpern                   phalpern@truffle.ultranet.com

I am self-employed. Therefore, my opinions *do* represent
those of my employer.
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: Pavel Kalugin <kalugin@lps.u-psud.fr>
Date: 1996/11/26
Raw View
Let the class X have a user defined operator ">":

bool X::operator >(const X&) const;

Then, what happens if the following STL operator template
slips into the scope:

template <class T1, class T2>
inline bool operator>(const T1& x, const T2& y) {
    return y < x;
}

Will this ambiguate the previous declaration? My experience
is that under GCC 2.7.2 it does, but is it a standard behavior?

Thanks,
-Pavel
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: vandevod@cs.rpi.edu (David Vandevoorde)
Date: 1996/11/26
Raw View
>>>>> "PK" == Pavel Kalugin <kalugin@lps.u-psud.fr> writes:
PK> Let the class X have a user defined operator ">":
PK> bool X::operator >(const X&) const;

PK> Then, what happens if the following STL operator template
PK> slips into the scope:

PK> template <class T1, class T2>
PK> inline bool operator>(const T1& x, const T2& y) {
PK>     return y < x;
PK> }

PK> Will this ambiguate the previous declaration? My experience
PK> is that under GCC 2.7.2 it does, but is it a standard behavior?

Prior to introducing partial specialization (and the associated
partial ordering), it did correspond to an ambinguity. Now, I think
it no longer does, but I know only one compiler which currently
supports the new rules in this context.

 Daveed


[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Alexandre Oliva <oliva@dcc.unicamp.br>
Date: 1996/11/26
Raw View
Pavel Kalugin writes:

> Let the class X have a user defined operator ">":
> bool X::operator >(const X&) const;

> Then, what happens if the following STL operator template
> slips into the scope:

> template <class T1, class T2>
> inline bool operator>(const T1& x, const T2& y) {
>     return y < x;
> }

> Will this ambiguate the previous declaration? My experience
> is that under GCC 2.7.2 it does, but is it a standard behavior?

No, non-templates are preferred instead of templates.  It is a bug in
gcc, which should be fixed in the next major release.

--
Alexandre Oliva
mailto:oliva@dcc.unicamp.br
Universidade Estadual de Campinas, SP, Brasil


[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Pavel Kalugin <kalugin@pc358.lps.u-psud.fr>
Date: 1996/11/26
Raw View
Just found the following un the ANSI draft (april 1995):

--------------------------------------------------------
2 Defining  a  function  with the same type as a template specialization
  that is called is ill-formed.  [Example:
          template<class T> T max(T a, T b) { return a>b?a:b; }
          int max(int a, int b) { return a>b?a:b; }

          void f(int x, int y)
          {
                  max(x,y); // error: duplicate definition of max()
          }
  If the two definitions of max() are not in the same  translation  unit
  the  diagnostic  is not required.  If a separate definition of a func=AD
  tion max(int,int) is needed, the specialization syntax  can  be  used.
  If the conversions enabled by an ordinary declaration are also needed,
  both can be used.
          template<class T> T max(T a, T b) { return a>b?a:b; }
          int max<>(int a, int b) { /* ... */ }

          void g(char x, int y)
          {
                  max(x,y); // error: no exact match, and no conversions
allowed
          }

          int max(int,int);

          void f(char x, int y)
          {
                  max(x,y); // max<int>(int(x),y)
          }
   --end example]
------------------------------------
(14.10.5.2). That is, there is no bug in GCC at this point. Unless
I misunderstand something, using STL expose all your classes=20
that possess one of the four operators !=3D, >, <=3D or >=3D to=20
possible ambiguation. This is too bad to be true...=20

-Pavel


[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: bradds@concentric.net (Bradd W. Szonye)
Date: 1996/11/27
Raw View
Pavel Kalugin <kalugin@pc358.lps.u-psud.fr> wrote in article
<329B5DF1.2AE6EE10@pc358.lps.u-psud.fr>...
>Just found the following un the ANSI draft (april 1995):

>2 Defining  a  function  with the same type as a template specialization
>  that is called is ill-formed.  [Example:
>          template<class T> T max(T a, T b) { return a>b?a:b; }
>          int max(int a, int b) { return a>b?a:b; }
>
>          void f(int x, int y)
>          {
>                  max(x,y); // error: duplicate definition of max()
>          }
>------------------------------------
>(14.10.5.2). That is, there is no bug in GCC at this point. Unless
>I misunderstand something, using STL expose all your classes
>that possess one of the four operators !=, >, <= or >= to
>possible ambiguation. This is too bad to be true...

It's not all that bad, unless you're "using namespace std" or "using
std::operator X". Otherwise, the operator templates are only visible within
namespace std (and the library is careful to define things in terms of
less<T> or operator<, which it does not define). If you're using
std::operator>, and your class does not have the usual semantics for
operator>, then you specialize your operator from the template like

template<> operator> <T, T> (T const&, T const&);

If you're not "using" the template, then name lookup doesn't find the
versions in namespace std for code in the global (or your own) namespace.

(Just as an aside, does anyone have any clue why my newsreader insisted on
thinking this message was posted in the Cyrillic alphabet? I don't read
news headers well enough to say. Email me--don't post--as this particular
question is off-topic.)
--
Bradd W. Szonye
bradds@concentric.net
http://www.concentric.net/~bradds
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: bradds@concentric.net (Bradd W. Szonye)
Date: 1996/11/27
Raw View
Pavel Kalugin <kalugin@pc358.lps.u-psud.fr> wrote in article
<329B5DF1.2AE6EE10@pc358.lps.u-psud.fr>...
>Just found the following un the ANSI draft (april 1995):

>2 Defining  a  function  with the same type as a template specialization
>  that is called is ill-formed.  [Example:
>          template<class T> T max(T a, T b) { return a>b?a:b; }
>          int max(int a, int b) { return a>b?a:b; }
>
>          void f(int x, int y)
>          {
>                  max(x,y); // error: duplicate definition of max()
>          }
>------------------------------------
>(14.10.5.2). That is, there is no bug in GCC at this point. Unless
>I misunderstand something, using STL expose all your classes
>that possess one of the four operators !=, >, <= or >= to
>possible ambiguation. This is too bad to be true...

It's not all that bad, unless you're "using namespace std" or "using
std::operator X". Otherwise, the operator templates are only visible within
namespace std (and the library is careful to define things in terms of
less<T> or operator<, which it does not define). If you're using
std::operator>, and your class does not have the usual semantics for
operator>, then you specialize your operator from the template like

template<> operator> <T, T> (T const&, T const&);

If you're not "using" the template, then name lookup doesn't find the
versions in namespace std for code in the global (or your own) namespace.

(Just as an aside, does anyone have any clue why my newsreader insisted on
thinking this message was posted in the Cyrillic alphabet? I don't read
news headers well enough to say. Email me--don't post--as this particular
question is off-topic.)
--
Bradd W. Szonye
bradds@concentric.net
http://www.concentric.net/~bradds


[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Alexandre Oliva <oliva@dcc.unicamp.br>
Date: 1996/11/28
Raw View
Pavel Kalugin writes:

> Just found the following un the ANSI draft (april 1995):
> --------------------------------------------------------
> 2 Defining  a  function  with the same type as a template specialization
>   that is called is ill-formed.  [Example:
>           template<class T> T max(T a, T b) { return a>b?a:b; }
>           int max(int a, int b) { return a>b?a:b; }

This restriction no longer exists.  The current DWP does allow
non-template functions to have the same signature a template function
has, and the non-template version is preferred, unless the template is
explicitly qualified. That is:

void foo() {
  max(1,2);       // will invoke non-template function, but
  max<int>(1,2);  // will invoke template function
}

> (14.10.5.2). That is, there is no bug in GCC at this point. Unless
> I misunderstand something, using STL expose all your classes
> that possess one of the four operators !=, >, <= or >= to
> possible ambiguation. This is too bad to be true...

It actually WAS too bad to be true, so it was fixed. :-)

--
Alexandre Oliva
mailto:oliva@dcc.unicamp.br
Universidade Estadual de Campinas, SP, Brasil
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: lars.farm@ite.mh.se (Lars Farm)
Date: 1996/11/28
Raw View
Alexandre Oliva <oliva@dcc.unicamp.br> wrote:

> Pavel Kalugin writes:
>
> > Just found the following un the ANSI draft (april 1995):
> > --------------------------------------------------------
> > 2 Defining  a  function  with the same type as a template specialization
> >   that is called is ill-formed.  [Example:
> >           template<class T> T max(T a, T b) { return a>b?a:b; }
> >           int max(int a, int b) { return a>b?a:b; }
>
> This restriction no longer exists.  The current DWP does allow
> non-template functions to have the same signature a template function
> has, and the non-template version is preferred, unless the template is
> explicitly qualified. That is:
>
> void foo() {
>   max(1,2);       // will invoke non-template function, but
>   max<int>(1,2);  // will invoke template function
> }

This is for an exact match. What about inheritance:

  class base{};
  class derived : public base {};

  template<class T> void f( const T& );
  void f( const base& );

  void foo() {
    derived d;
    f( d );         // which f() is called?
                    //    void f(const base&) or
  }                 //    void f<derived>(const derived&)


--
Lars Farm, lars.farm@ite.mh.se


[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]