[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