0

我一直在仔细研究 C++ 中的模板,我发现似乎没有一套严格的术语来清楚地识别和区分/消除使用模板时可能出现的每个句法元素,这很有挑战性。

例如,Josuttis 和 Vandevoorde 经常参考(和首选)的关于模板的书《C++ 模板:完整指南》是一本出色的书——但即使是那本书也没有明确指出涉及模板的每个句法元素的严格术语。相反,从上下文中可以清楚地看到含义。

考虑下面这个简单的例子,我相信它突出了涉及模板的 11 个不同的相关句法组件。

#include <iostream>
#include <vector>

template
    <
        typename 

            M1, // <-- (1) "Primary template declaration template parameter
                //          identifier"

        typename M2 // ditto

    > // <-- (2) (entire <...> syntactic element) "Primary template declaration
      //                                           template parameter list"

class Foo
{

    // <-- (3) "Primary class template definition"

};

template
    <
        typename

            T1, // <-- (4) "Template specialization declaration template
                //          parameter identifier"

        typename A1, typename M2 // ditto

    > // <-- (5) (entire <...> syntactic element) "Template specialization
      //                                           declaration template
      //                                           parameter list"

class Foo
    <

        std::vector<T1, A1> &, // <-- (6) "Template specialization
                               //          declaration TEMPLATE PARAMETER
                               //          SPECIALIZATION ARGUMENT"
                               //          (?)

        M2

    > // <-- (7) (entire <> syntactic element) "Template specialization
      //                                        declaration TEMPLATE PARAMETER
      //                                        SPECIALIZATION ARGUMENT LIST"
      //                                        (?)

{

    // <-- (8) "Template specialization class definition"

};

int main()
{
    Foo
        <

            std::vector<int> &, // <-- (9) "Template class instantiation
                                //          template parameter"
                                //          (?) 

            int // diito

        > // <-- (10) (entire <> syntactic element) "Template class
          //                                         instantiation template
          //                                         parameter list"
          //                                         (?)

    f; // <-- (11) "Template class instantiation instance variable name"

}

在代码示例中,我指出了 11 个不同的与模板相关的句法元素,并为每个元素提供了我建议的严格分类标签。

我怀疑我为这些元素中的大多数使用了正确的分类标识符(但如果我错了,请纠正我)。

然而,句法项 (6)、(7)、(9) 和 (10) 是棘手的——例如,在 (6) 和 (7) 的情况下,存在模板特化的情况,其中对of 尖括号<>出现两次,因此在用于指示出现在这两个非常不同的尖括号对的尖括号之间的参数(参数?)的标识符中必须存在分类区别。模板实例化(9) 和 (10) 涉及尖括号的另一种使用,因此出现在这些括号内的参数也必须有自己的识别分类标识符。

也许,在这个问题中,我使用了适当的严格术语,但我想知道:

  1. 有没有比我用过的更简单严谨的术语?

  2. 我是否在识别标签中使用了无关和/或不必要的词?

  3. 我的识别标签中是否缺少单词?

  4. 我使用的识别标签是否正确?

4

1 回答 1

1

我认为您不需要过多关注模板参数,它们在任何地方都扮演着相同的角色。一些非常重要的术语,其中一些您没有提到:

template<typename T> struct foo;是主模板的声明。
template<typename T> struct foo<T*>;是部分专业化的声明。
template<> struct foo<int>;是显式特化的声明。

当遇到诸如变量定义之类的东西时,有时需要foo<double> f;对适当的特化进行实例化。特别是,如果声明了明确的特化,则不需要它。非正式地,隐式实例化的过程是对以下内容的重写:

template<typename T> struct foo {
    void bar();
};
template<typename T> void foo<T>::bar() {}

对此:

template<typename T> struct foo;

template<> struct foo<double> {
    void bar();
};
template<> void foo<double>::bar() {}

也可以在任何给定的 TU 中请求实例化,这称为显式实例化:

// explicit instantiation declaration, C++11
extern template class foo<double>;
// explicit instantiation definition
template class foo<double>;

// can also instantiate a member of the template more specifically:
template void foo<double>::bar();

顾名思义,显式实例化定义是一种保证模板(以及,如果适用的话,它的所有成员)被实例化的方法。显式实例化声明有点相反——它们抑制隐式实例化,而是使用匹配的显式实例化定义产生的实例化。显式实例化功能的总体意图是为程序提供“引导”编译器以帮助缩短编译时间的方法。

我不会评论显式实例化的实现质量——事实上,请注意显式实例化声明是最近添加的。我认为您可以在 C++ 上花费大量时间,而无需遇到或需要任何一个特性。

也许令人困惑的是,实际上很多人会非正式地使用术语“模板实例化”而不是“模板专业化”。为了澄清,以下都是模板特化:std::deque<int>,std::less<T*>std::vector<bool>(当然不是同一个类模板!)。并非所有模板专业化的使用或提及都会触发或引用模板实例化。我认为不需要知道何时或是否触发模板实例化这一事实是模板的一个方便的特性。

实际上有一个东西叫做实例化点:

// Declare template
template<typename T> struct foo;

// Use template and mention template specialization
// but no instantiation is required here!
typedef foo<int> F;

// Point of instantiation of foo<int>
// an actual definition of foo<int> is needed here
F f;

(虽然我在这里只使用了类模板,但我所描述的所有内容都适用于整个模板,包括函数模板。)

于 2012-11-28T13:45:00.963 回答