Partial specializations that does not specialize any template arguments although are still accepted.

108 views
Skip to first unread message

piotrek...@gmail.com

unread,
Oct 13, 2016, 8:10:59 AM10/13/16
to ISO C++ Standard - Discussion
Hi All,

Let's consider the following code:

template <typename T, int N1, int N2>
class myclass
{
public:
 
void f() { std::cout << "not specialized, N1 = " << N1 << ", N2 = " << N2 << "\n"; }
};

int main()
{
  myclass
<double,10,20> mc;
  mc
.f();
}

The output of the above program is obviously:

not specialized, N1 = 10, N2 = 20

Adding the following specialization will cause compilation error:

template <typename T, int N1, int N2>
class myclass<T,N1,N2>
{
public:
 
void f() { std::cout << "specialized, N1 = " << N1 << ", N2 = " << N2 << "\n"; }
};

the error message says:

partial specialization ‘myclass<T, N1, N2>’ does not specialize any template arguments

So far everything is clear. But when I change the order of the parameters in the parameter list, then unexpectedly the code starts to compile:

template <typename T, int N1, int N2>
class myclass
{
public:
 
void f() { std::cout << "not specialized, N1 = " << N1 << ", N2 = " << N2 << "\n"; }
};

template <int N1, int N2, typename T>
class myclass<T,N1,N2>
{
public:
 
void f() { std::cout << "specialized, N1 = " << N1 << ", N2 = " << N2 << "\n"; }
};

int main()
{
  myclass
<double,10,20> mc;
  mc
.f();
}

The above code produces:

specialized, N1 = 10, N2 = 20

The result is the same for gcc 4.8.1 and clang 3.3.

Why the above code compile even though the partial specialization doesn't specialize any template arguments?

Robert Haberlach

unread,
Oct 13, 2016, 8:34:51 AM10/13/16
to std-dis...@isocpp.org
AFAICS, that code is ill-formed with a diagnostic required by [temp.class.spec]/(8.2). Perhaps implementations don't actually check that the partial
specialization is more specialized, but use a heuristic that checks whether the declared template parameters are simply enumerated in order in the
argument list?

On 10/13/2016 01:10 PM, piotrek...@gmail.com wrote:
> Hi All,
>
> Let's consider the following code:
>
> |
> template<typenameT,intN1,intN2>
> classmyclass
> {
> public:
> voidf(){std::cout <<"not specialized, N1 = "<<N1 <<", N2 = "<<N2 <<"\n";}
> };
>
> intmain()
> {
> myclass<double,10,20>mc;
> mc.f();
> }
> |
>
> The output of the above program is obviously:
>
> not specialized, N1 = 10, N2 = 20
>
> Adding the following specialization will cause compilation error:
>
> |
> template<typenameT,intN1,intN2>
> classmyclass<T,N1,N2>
> {
> public:
> voidf(){std::cout <<"specialized, N1 = "<<N1 <<", N2 = "<<N2 <<"\n";}
> };
> |
>
> the error message says:
>
> partial specialization ‘myclass<T, N1, N2>’ does not specialize any template arguments
>
> So far everything is clear. But when I change the order of the parameters in the parameter list, then unexpectedly the code starts to compile:
>
> |
> template<typenameT,intN1,intN2>
> classmyclass
> {
> public:
> voidf(){std::cout <<"not specialized, N1 = "<<N1 <<", N2 = "<<N2 <<"\n";}
> };
>
> template<intN1,intN2,typenameT>
> classmyclass<T,N1,N2>
> {
> public:
> voidf(){std::cout <<"specialized, N1 = "<<N1 <<", N2 = "<<N2 <<"\n";}
> };
>
> intmain()
> {
> myclass<double,10,20>mc;
> mc.f();
> }
> |
>
> The above code produces:
>
> specialized, N1 = 10, N2 = 20
>
> The result is the same for gcc 4.8.1 and clang 3.3.
>
> Why the above code compile even though the partial specialization doesn't specialize any template arguments?
>
> --
>
> ---
> You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to std-discussio...@isocpp.org
> <mailto:std-discussio...@isocpp.org>.
> To post to this group, send email to std-dis...@isocpp.org <mailto:std-dis...@isocpp.org>.
> Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Reply all
Reply to author
Forward
0 new messages