https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86193

Jason Merrill <jason at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |SUSPENDED

--- Comment #2 from Jason Merrill <jason at gcc dot gnu.org> ---
(In reply to Jonathan Wakely from comment #1)
> (In reply to zhonghao from comment #0)
> > I tried the latest g++, but it does not accept the code. BTW, clang++
> > accepts the code. Is this a recurring bug?
> 
> No, it's rejected for a different reason, so it's not the same bug.
> 
> It started to be rejected with r243868:
> 
>     Check that a partial specialization is more specialized.

Indeed.

[temp.class.spec]: The specialization shall be more specialized than the
primary template (17.6.5.2).

Checking that is equivalent to resolving the partial ordering of function
templates in

template <class T>
struct identity
{
 typedef T type;
};

template <class T, typename T::type A>
struct foo {};

template <class T1, typename T1::type A1>
void fn(foo<T1,A1>) = delete;

template <class T2, T2 A2>
void fn(foo<identity<T2>,A2>);

int main()
{
  fn(foo<identity<int>,0>()); // error here                                     
}

which, similarly, G++ (and EDG) rejects, and clang accepts.

I think G++ is right here:  when we try to deduce values for T1 and A1 in
partial ordering, we deduce T1 to identity<T2>, but we can't deduce anything
for A1 because we don't know that the types are compatible.  You can work
around that by changing your partial specialization to

template <class T, typename identity<T>::type A>
struct foo<identity<T>, A> {};

This does seem like an underspecified area in the standard.

Reply via email to