模板类不完全专门化 [英] Template class incomplete specialization

查看:130
本文介绍了模板类不完全专门化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了一个有趣的点,我不能解释或找到解释。考虑下面的模板定义(使用mingw g ++ 4.6.2编译):

  template< typename T,typename S& 
class Foo
{
public:
void f(){}
void g(){}
};如果我们想要,我们可以完全专门化任何单个成员函数:


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

失败并出现无效使用不完整类型类Foo <...>'错误:

 模板< typename T ,类型名S> 
void Foo< T,S *> :: f()
{
}

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

我不知道为什么。这是一个有意识的设计决定,以避免一些我不能预见的问题吗?是否是监督?



提前感谢。

解决方案

部分专业化的概念仅存在于类模板(由§14.5.5描述)和成员模板(即本身是模板函数的模板类的成员,由§14.5.5.3/ 2描述)。它不存在于类模板的普通成员,也不存在于函数模板–因为它不是由标准描述的。



现在,你可能会认为通过给成员函数的部分特化的定义,如

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

隐含地定义类模板的部分特化: Foo gt;


(§14.5.5/ 2)每个标准都明确排除 类模板部分专门化是一个独特的模板,应为模板部分专门化(14.5.5.3)的成员提供定义。



(§14.5.5.3/ 1) [...]类模板部分专门化的成员与主模板的成员无关。应定义以需要定义的方式使用的类模板部分特化成员;主模板的成员的定义从不用作类模板部分特化的成员的定义。 [...]


后者意味着不可能通过简单的给出其成员之一的定义:该成员的存在不会遵循主模板的定义,因此定义它等同于定义 成员函数



另一方面,显式特化

的概念, / strong>(或者您称为全特化)存在于类模板的成员函数。它由标准明确描述:


(§14.7.3/ 1)以下任何一种显式特化:

[...]

- 类模板的成员函数

[...]

可以通过template<> [...]


§14.7.3/ 14描述详细信息:


(§14.7.3/ 14)类模板的成员或成员模板可以显式专用于类模板的给定隐式实例化,即使成员或成员模板在类模板定义中定义。 [...]


因此,对于成员的显式特化,类模板的其余部分的实例化隐含地–它是从主模板定义派生的,或者如果定义了任何部分专门化。


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?

Thanks in advance.

解决方案

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.

这篇关于模板类不完全专门化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆