Topic: Explicit specialization of templated entity


Author: Nikolay Ivchenkov <tsoae@mail.ru>
Date: Sun, 25 Oct 2009 10:11:51 CST
Raw View
There is one restriction that is unclear for me.

C++03 - 14.7/5: "No program shall [...] specialize a template more
than once for a given set of template-arguments. An implementation is
not required to diagnose a violation of this rule."
N2960 - 14.8/5: "For a given template and a given set of template-
arguments [...] an explicit specialization shall be defined at most
once in a program (according to 3.2)"

Does it mean that we can't provide two identical explicit
specializations of a class template in two separate translation units?
If so then, for example, we even can't include <limits> header in two
source files (e.g. we will have two definitions of the same
specialization std::numeric_limits<float> in the program).

I don't see appropriate terms in the standard, so I will try to
explain what I expected to see in the language specification using my
own definitions:

Unless otherwise specified, 'class template' means either a non-member
class template or member class template.
Unless otherwise specified, 'function template' means either a non-
member function template or member function template.

'Templated class' is either a class template or a member class of a
templated class.
'Templated function' is either a function template or a member
function of a templated class.
'Templated entity' is one of: a templated class, or a templated
function, or a static data member of a templated class.

Expected meaning of [temp.expl.spec]/1:

An explicit specialization of any of the following:
    >>templated class<<
    non-deleted >>templated function<<
    static data member of a >>templated class<<
can be declared by a declaration introduced by template<>

Note that the specification in N2960 does not cover the following
code:

template <class T>
   struct X
{
   struct Y
   {
     void f() {}
   };
};
template <>
   void X<int>::Y::f() {} // should be well-formed?

Expected meaning of [temp.spec]/5:

For a given >>templated entity<< and a given set of template-
arguments,
    an explicit instantiation definition shall appear at most once in a
program,
    both an explicit instantiation and a declaration of an explicit
specialization shall not appear in a program unless the explicit
instantiation follows a declaration of the explicit specialization,
and
    >>if the templated entity is a templated class then<< an explicit
specialization shall be defined at most once in >>every translation
unit<< and the definition shall be the same in each case (according to
3.2),
    >>if the templated entity is either a templated function or a static
data member of a templated class then<< an explicit specialization
shall be defined at most once in a program (according to 3.2).


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "Johannes Schaub (litb)" <schaub-johannes@web.de>
Date: Mon, 26 Oct 2009 00:18:32 CST
Raw View
Nikolay Ivchenkov wrote:

> There is one restriction that is unclear for me.
>
> C++03 - 14.7/5: "No program shall [...] specialize a template more
> than once for a given set of template-arguments. An implementation is
> not required to diagnose a violation of this rule."
> N2960 - 14.8/5: "For a given template and a given set of template-
> arguments [...] an explicit specialization shall be defined at most
> once in a program (according to 3.2)"
>
> Does it mean that we can't provide two identical explicit
> specializations of a class template in two separate translation units?
> If so then, for example, we even can't include <limits> header in two
> source files (e.g. we will have two definitions of the same
> specialization std::numeric_limits<float> in the program).
>
14.8/4 says " A specialization is a class, function, or class member that is
either instantiated or explicitly specialized".

Referring to 3.2 using "according to ..." is intended to say "it shall be
defined at most once when 3.2 says so.", i believe, although that's not at
all clear. If interpreted this way, then including <limits> more than once
is fine, because we can define a class entity multiple times, provided all
definitions of it satisfy 3.2.

For an explicit specialization of a funtion template, rules of 3.2 will
enforce that each definition will have the inline specifier.

In any case, i agree with you that the wording is confusing and i think it
should rather say "An explicit specialization definition defines a class,
function or template, and should appear at most once according to the rules
of 3.2 for class and template definitions." - or something similar.

What i don't understand in 14.8/4 is: The following is an explicit
specialization, but it's still not a class, but rather a class template:

template<typename T> struct A {
   template<typename U> struct B { };
};
template<> template<typename U> struct A<int>::B { };

I'm not sure what such a thing is called: "specialization of a member class
template of a class template" is ambiguous i think, because it can aswell
mean

template<> template<> struct A<int>::B<int> { };

It seems to me it is specified by 14.8.3/20 "A specialization of a member
function template or member class template of a non-specialized class
template is itself a template.", but that one just seems to apply to the
following scenario:

template<typename S> struct Q {
   template<typename T> struct A {
     template<typename U> struct B { };
   };
};

template<> template <typename T> template<typename U> struct Q<int>::A<T>::B
{ };

So i think it should rather say "An explicit specialization of a member
function template or member class template for which some template
parameters are not specified is itself a template." (compare with wording of
3.2/5 "template specialization for which some template parameters are not
specified").

> I don't see appropriate terms in the standard, so I will try to
> explain what I expected to see in the language specification using my
> own definitions:
>
> Unless otherwise specified, 'class template' means either a non-member
> class template or member class template.
> Unless otherwise specified, 'function template' means either a non-
> member function template or member function template.
>
> 'Templated class' is either a class template or a member class of a
> templated class.
> 'Templated function' is either a function template or a member
> function of a templated class.
> 'Templated entity' is one of: a templated class, or a templated
> function, or a static data member of a templated class.
>
This makes sense to me. I've always been confused about *what* entity a
function member of a class template actually is. It's sure that it's a
template, but on the other side, it's not a member function template. So i
found like you that it's some "template" that syntactically is a function,
which i think you termed nicely as "templated function" etc.

I neither see explicit wording of this, but what i find interesting is a
comment in an example in 14.6.1.1/1, which says the member function
declarations of the class template "declare three function templates.". This
is non-normative, but it seems to indicate some weird means that's yet
unknown to me.

> Expected meaning of [temp.expl.spec]/1:
>
> An explicit specialization of any of the following:
>     >>templated class<<
>     non-deleted >>templated function<<
>     static data member of a >>templated class<<
> can be declared by a declaration introduced by template<>
>
This makes sense to me.

> Note that the specification in N2960 does not cover the following
> code:
>
> template <class T>
>    struct X
> {
>    struct Y
>    {
>      void f() {}
>    };
> };
> template <>
>    void X<int>::Y::f() {} // should be well-formed?
>
I can also not find this being specified when "f" is not treated as a
function template. Apparently here too there are some things yet unknown to
me.

> Expected meaning of [temp.spec]/5:
>
> For a given >>templated entity<< and a given set of template-
> arguments,
>     an explicit instantiation definition shall appear at most once in a
> program,
>     both an explicit instantiation and a declaration of an explicit
> specialization shall not appear in a program unless the explicit
> instantiation follows a declaration of the explicit specialization,
> and
>     >>if the templated entity is a templated class then<< an explicit
> specialization shall be defined at most once in >>every translation
> unit<< and the definition shall be the same in each case (according to
> 3.2),
>     >>if the templated entity is either a templated function or a static
> data member of a templated class then<< an explicit specialization
> shall be defined at most once in a program (according to 3.2).
>
>
This also makes sense to me. I think it clears up the matters as far as i
can see.

--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "Johannes Schaub (litb)" <schaub-johannes@web.de>
Date: Mon, 26 Oct 2009 13:12:15 CST
Raw View
Johannes Schaub (litb) wrote:

> Nikolay Ivchenkov wrote:
>
>> There is one restriction that is unclear for me.
>>
>> C++03 - 14.7/5: "No program shall [...] specialize a template more
>> than once for a given set of template-arguments. An implementation is
>> not required to diagnose a violation of this rule."
>> N2960 - 14.8/5: "For a given template and a given set of template-
>> arguments [...] an explicit specialization shall be defined at most
>> once in a program (according to 3.2)"
>>
>> Does it mean that we can't provide two identical explicit
>> specializations of a class template in two separate translation units?
>> If so then, for example, we even can't include <limits> header in two
>> source files (e.g. we will have two definitions of the same
>> specialization std::numeric_limits<float> in the program).
>>
> 14.8/4 says " A specialization is a class, function, or class member that
> is either instantiated or explicitly specialized".
>
> [snippet]
>
> What i don't understand in 14.8/4 is: The following is an explicit
> specialization, but it's still not a class, but rather a class template:
>
> template<typename T> struct A {
>    template<typename U> struct B { };
> };
> template<> template<typename U> struct A<int>::B { };
>
Ah, i'm silly. This is a class member. It's covered by 14.8/4 :)

> I'm not sure what such a thing is called: "specialization of a member
> class template of a class template" is ambiguous i think, because it can
> aswell mean
>
> template<> template<> struct A<int>::B<int> { };
>
> It seems to me it is specified by 14.8.3/20 "A specialization of a member
> function template or member class template of a non-specialized class
> template is itself a template.", but that one just seems to apply to the
> following scenario:
>
> template<typename S> struct Q {
>    template<typename T> struct A {
>      template<typename U> struct B { };
>    };
> };
>
> template<> template <typename T> template<typename U> struct
> Q<int>::A<T>::B
> { };
>
> So i think it should rather say "An explicit specialization of a member
> function template or member class template for which some template
> parameters are not specified is itself a template." (compare with wording
> of 3.2/5 "template specialization for which some template parameters are
> not specified").
>
I still wonder what makes  14.8.3/20 different from the case where only A
and B are involved, i.e where we specialize a member class template of a
class template where we don't specify the arguments for the member class
template. Or how the heck is it called? Why does it explicitly need to say
that in the Q->A->B case the entity is still a template, but not in the A->B
case?? In any case, i'm sorry for the double post, but i had to fix the
silly oversight of me above -.-

--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]