One for the language lawyers

Martin Staley staley@t7.lanl.gov
Wed Feb 20 16:54:00 GMT 2002


Okay, here's one for the language lawyers.  KCC (EDG front-end) accepts the
following code; g++ v3.03 does not.  I'm sending this e-mail both to the KAI C++
support e-mail address and the g++ bug-report e-mail address, so y'all can duke
it out. ;-)  I believe EDG is correct; that is, that the following is legal C++
and should print "foo":

     #include <iostream>

     // fun #1
     template<class T>
     T fun(const T &)
     {
        std::cout << "foo" << std::endl;
        return 0;
     }

     // fun #2
     // Yes, I know this differs only in return type, BUT see below...
     template<class T>
     typename T::value_type fun(const T &)
     {
        std::cout << "bar" << std::endl;
        return 0;
     }

     int main(void)
     {
        fun(1);
     }

The g++ bugs people told me this morning:

> Not a bug [in g++].
>
>     Function declarations that differ only in the return type cannot
>     be overloaded.
>
> Thus sayeth the standard, [13.1]/2.

And they later wrote:

> User error.  Functions differing only in their return types
> may not be overloaded.

Ah, but we aren't dealing with functions; we're dealing with function TEMPLATES,
which are completely different (and more gnarly) animals entirely!
Thus [13.1]/2 is not applicable to my code.

>From a detailed reading of the relevant sections in ISO/IEC 14882:1998(E) on
function TEMPLATES (not functions), I conclude the following:

 * Template argument deduction precedes overload resolution.
   [14.8.3]/1 states, "For each template argument, if the argument deduction
   and checking succeeds, the template-arguments (deduced and/or explicit)
   are used to instantiate a single function template specialization which is
   added to the candidate functions set to be used in overload resolution."

 * The "signature" of a function template includes its return type.
   [14.5.5.1]/4 states, "The signature of a function template consists of its
   function signature, its return type and its template parameter list."  In
   particular, the first sentence of the following paragraph, [14.5.5.1]/5, is
   directly relevant to my example.

 * From [14.8.2]/4: "When all template arguments have been deduced, all uses
   of template parameters in nondeduced contexts [e.g in the return type
   T::value_type in my example] are replaced with the corresponding deduced
   argument values.  If the substitution results in an invalid type [!!], as
   described above, type deduction fails."

One example of an "invalid type, as described above" appears in [14.8.2]/2,
bullet three, sub-bullet two:

   template<class T> int f(typename T::B*);
   int i = f<int>(0);

This particular example differs a bit from mine, because it uses an explicit
template argument list, but the principle is the same: whether T=int is explicit
or deduced, T::B* for T=int makes no sense---it's an invalid type.

Soooooo...here's my take on my example:

 1) Both versions of fun() have the same parameters.  T=int is deduced in both
    cases.

 2) The return type T::value_type (part of the function template's signature)
    in fun #2 is replaced with the deduced argument value T=int, and results in
    an INVALID TYPE int::value_type.

 3) Therefore, type deduction fails for fun #2.

 4) Therefore, fun #2 is not added to the candidate functions for overload
    resolution.

 4) Overload resolution now occurs: fun #1 is the only candidate, so there's
    no ambiguity, so the code is legal C++.

Okay guys and gals, who's right?  In this instance, I'll put my money on EDG.
In my real code, I'm making good use of the fact (if it is indeed a fact) that
a potential function template specialization is excluded from the viable
candidates for overload resolution if type substitution in a nondeduced context
results in an invalid type.  Workarounds aren't too difficult, but it's better
to have compilers that work consistently for legal, well-defined C++, than to
spend time finding workarounds. :-)

Martin
------------------------------------------------------------------------
Martin Staley                                         (tel) 505-665-4963
T-7, Mathematical Modeling and Analysis               (fax) 505-665-5757
M.S. B-284                                            staley@t7.lanl.gov
Los Alamos National Laboratory
Los Alamos, NM 87545                    http://cnls-www.lanl.gov/~staley
------------------------------------------------------------------------



More information about the Gcc-bugs mailing list