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