public inbox for gcc-prs@sourceware.org
help / color / mirror / Atom feed
From: "Giovanni Bajo" <giovannibajo@libero.it>
To: nobody@gcc.gnu.org
Cc: gcc-prs@gcc.gnu.org,
Subject: Re: c++/7033: [3.3/3.4 regression] [2003-05-30] Partial template specializations accepted even if a template parameter is used in a non-deduced context
Date: Tue, 06 May 2003 23:56:00 -0000	[thread overview]
Message-ID: <20030506235600.30874.qmail@sources.redhat.com> (raw)

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 5337 bytes --]

The following reply was made to PR c++/7033; it has been noted by GNATS.

From: "Giovanni Bajo" <giovannibajo@libero.it>
To: "Theodore Papadopoulo" <Theodore.Papadopoulo@sophia.inria.fr>
Cc: <gcc-gnats@gcc.gnu.org>,
	<gcc-bugs@gcc.gnu.org>,
	<nobody@gcc.gnu.org>,
	<gcc-prs@gcc.gnu.org>,
	<Lionel.Champalaune@sophia.inria.fr>,
	"Gabriel DOS_REIS" <Gabriel.Dos_Reis@sophia.inria.fr>
Subject: Re: c++/7033: [3.3/3.4 regression] [2003-05-30] Partial template specializations accepted even if a template parameter is used in a non-deduced context 
Date: Wed, 7 May 2003 01:46:12 +0200

 Theodore Papadopoulo <Theodore.Papadopoulo@sophia.inria.fr> wrote:
 
 > First §14.8.2.4p4 deals with "Function template specializations" not
 > with "Class template specializations". The program might be invalid
 > but not for this reason.
 
 Sure, but the deduction rules are exactly the same. It's clearly stated in
 §14.5.4.1p2 [temp.class.spec.match]: "A partial specialization matches a
 given actual template argument list if the template arguments of the partial
 specialization can be deduced from the actual template argument list
 (14.8.2)".
 
 Note that it refers _exactly_ to §14.8.2 as The Way to match a partial
 specialization. In fact, §14.8.2.4 is called "Deducing template arguments
 from a type", and §14.8.2 is "Template argument decuction". Those are _the_
 rules to deduce template arguments, either to deduce arguments for a
 function template call, or to match a partial specialization.
 
 > Second, the specialization can fully be deduced from the template
 > arguments (look again), so that your second affirmation is equally
 > wrong. Both T and V are given in the instanciation.
 
 No. You don't specify T and V in the instanciation. Let's look at it again:
 
 ---------------------------
 template <typename A, typename B> struct S;
 
 template <template <typename> class C,
            typename T,
            typename V>
  struct S<C<T>,typename C<T>::template it<V> >
 {
    [...]
 };
 
 template <typename> struct U {
      template <typename> struct it {
          it (int);
      };
  };
 
 typedef U<int>   c2i;
 S<c2i,  c2i::it<int> >::it it;
 ---------------------------
 
 You're specifiying two template parameters. These two template parameters
 are obviously the template parameters for the primary template, so we now
 know that [A = U<int>] and [B = U<int>::it<int>]. Now, the whole point is:
 is it possible to deduce C, T, V from these A,B? §14.8.2 is the arbiter here
 because it's where the deduction rules are specified.
 
 The first step is to deduce C<T> from [A = U<int>]. This is a easy, because
 [C = U] and [T = int]. This deduction succeeds because it's allowed
 _explicitally_ by §14.8.2.4p9, which says that TT<T> (for any
 template-template parameter TT and type T) is a deducible form (among
 others).
 
 The second step would be to deduce C<T>::it<V> from [B = U<int>::it<int>].
 Since C and T have been already deduced, the compiler will try deducing
 U<int>::it<V> from [B = U<int>::it<int>]. Now, I understand that here one
 could say "hey, it's easy, U=int and we're done", but this is not what the
 standard says. First, if you look into §14.8.2.4p9, such a format (inner
 template within a class) is not listed among the deducible forms. And if
 this was not enough, we still have §14.8.2.4p4, which says:
 
 "The non-deduced contexts are:
 [...]
 - The nested-name-specifier of a type what was specified using a
 qualified-id".
 
 There is also an example: "If a type is specified as A<T>::B<T2>, both T and
 T2 are non-deduced". And isn't this _exactly_ our case?
 
 This means that the compiler _cannot_ deduce V in U<int>::it<V> from [B =
 U<int>::it<int>]. Which means that deduction fails for the partial
 specialization, and the primary template is instanciated.
 
 I agree this might look strange at first sight, but this is exactly how
 deduction works. Inner templates make deduction fails, always. Even if it
 was simply "A<T>::B", deduction for T would fail (it's listed as another
 example in the same paragraph).
 
 > Actually, looking at the standard with Gaby today, it looks like that
 > by  §14.5.4.1p1, the unique specialization exactly matched by all the
 > template parameters (which is the case here) should be selected....
 
 §14.5.4.1p1 only says that if there is a single matching specialization, the
 instantion is generated for that specialization, otherwise partial ordering
 kicks in. My point is that your instanciation does _NOT_ match that partial
 specialization, so the instantiation must be generated from the primary
 template.
 
 > I do not definitely claim that the example should compile because I
 > do not know all the arcanes of the standard with this respect, but I
 > have not yet seen an argument that forbids it. And moreover,
 > forbidding this would be extremely surprising for the users without a
 > proper message explaining the reasons for that...
 
 In fact, what the compiler should do is to reject the partial specialization
 itself when it's defined, because it's ill-formed (it could never be matched
 since V appears only in a non-deduced context). An error message like
 "partial specialization is invalid because template parameter V appears only
 in a non-deduced context" might be clear enough.
 
 Giovanni Bajo
 


             reply	other threads:[~2003-05-06 23:56 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-05-06 23:56 Giovanni Bajo [this message]
  -- strict thread matches above, loose matches on Subject: below --
2003-05-06 18:36 Theodore Papadopoulo
2003-05-05 11:36 Giovanni Bajo
2003-05-05 11:26 Giovanni Bajo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20030506235600.30874.qmail@sources.redhat.com \
    --to=giovannibajo@libero.it \
    --cc=gcc-prs@gcc.gnu.org \
    --cc=nobody@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).