[Bug c++/14007] [3.3/3.4/3.5 Regression] Incorrect use of const partial specialization for reference template argument
nathan at gcc dot gnu dot org
gcc-bugzilla@gcc.gnu.org
Fri Mar 19 14:27:00 GMT 2004
------- Additional Comments From nathan at gcc dot gnu dot org 2004-03-19 14:27 -------
given
template <typename T> struct X {}; // #1
template <typename T> struct X<const T>; //#2
template struct X<int&>; //#3
Does #3 instantiate #1 or #2? It seems obvious that #1 is what
is desired, but that is not what the standard says. The relevent
bits of the standard are the partial specialization rules [14.5.4.1]
and the ignoring of cv qualifiers on a reference type introduced
by a typedef or template parameter [8.3.2]/1
To determine which partial specializations match, we see if its
arguments can be deduced from the actual template argument list. In
this case, can we deduce a 'T const' from 'int &' ? [14.8.2] describes
template argument deduction, but primarily focusses on deduction of a
templated function. Presumable [14.8.2.4] is what applies here. In
this case P is 'T const' and A is 'int &'. Para1 tells us to find a
type such that when subtituted into P, will make that compatible with
A. Here 'int &' is such a type for T, because when substituted into
'T const', we ignore the const as the reference is introduced via a
template type. Hence partial specialization #2 deduces with T='int
&'.
However, if the rule in [8.3.2]/1 about ignoring cv qualifiers on
references does not apply during deduction, then presumably the
same applies to DR295, where CV qualifiers of function types
introduced via a typedef or template parameter are similarly not
ignored in deduction. If that is the case, does it apply during
deduction only in deduced contexts, or in both deduced and non-deduced
contexts? In either case, I can find nothing in the standard to
indicate this.
template <typename T> void Foo (T); // #1
template <typename T> void Foo (T const); // #2
static_cast <void (int &)> (Foo); // #1 or #2?
template <typename T> void Foo (T *); // #1
template <typename T> void Foo (T const *); // #2
void Baz ();
Foo (Baz); // which?
template <typename T> T const *Foo (T *); // #1
void Baz ();
Foo (Baz); // well formed?
template <typename T> void Foo (T *, T const * = 0);
void Baz ();
Foo (Baz); // well formed?
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=14007
More information about the Gcc-bugs
mailing list