Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I came across an interesting point that I wasn't able to explain or find an explanation for. Consider the following template definition (compiled with mingw g++ 4.6.2):

template <typename T, typename S>
class Foo
{
public:
    void f(){}
    void g(){}
};

Should we want to, we can fully specialize any single member function:

template <>
void Foo<char,int>::f() {}

But partial specialization fails with an "invalid use of incomplete type 'class Foo<...>'" error:

template <typename T, typename S>
void Foo<T,S*>::f()
{
}

template <typename T>
void Foo<T,int>::f()
{
}

And I can't figure out why. Is it a conscious design decision made to avoid some problem I can't foresee? Is it an oversight?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
411 views
Welcome To Ask or Share your Answers For Others

1 Answer

The notion of partial specialization only exists for class templates (described by §14.5.5) and member templates (i.e. members of a template class that are themselves template functions, described by §14.5.5.3/2). It does not exist for ordinary members of class templates, nor does it exist for function templates – simply because it is not described by the Standard.

Now, you might argue that by giving the definition of a partial specialization of a member function, such as

template <typename T>
void Foo<T,int>::f()
{ }

you implicitly define a partial specialization of the class template: Foo<T,int>. That, however, is explicitly ruled out by the Standard:

(§14.5.5/2) Each class template partial specialization is a distinct template and definitions shall be provided for the members of a template partial specialization (14.5.5.3).

(§14.5.5.3/1) [...] The members of the class template partial specialization are unrelated to the members of the primary template. Class template partial specialization members that are used in a way that requires a definition shall be defined; the definitions of members of the primary template are never used as definitions for members of a class template partial specialization. [...]

The latter implies that it is impossible to implicitly define a partial specialization by simply giving the definition of one of its members: The very existence of that member would not follow from the definition of the primary template, hence defining it is equivalent to defining a member function that wasn't declared, and that isn't allowed (even with non-template classes).

On the other hand, the notion of explicit specialization (or full specialization, as you call it) exists for member functions of class templates. It is explicitly described by the Standard:

(§14.7.3/1) An explicit specialization of any of the following:
[...]
— member function of a class template
[...]
can be declared by a declaration introduced by template<>; [...]

§14.7.3/14 describes the details:

(§14.7.3/14) A member or a member template of a class template may be explicitly specialized for a given implicit instantiation of the class template, even if the member or member template is defined in the class template definition. [...]

Hence, for explicit specializations of members, the instantiation of the rest of the class template works implicitly – it is derived from the primary template definition, or any partial specializations if defined.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...