0

私は C++ のテンプレートを注意深く研究してきましたが、テンプレートを使用して出現する可能性のあるすべての構文要素を明確に識別し、区別/明確化するための厳密な用語の確立されたセットがないように見えることは難しいと感じています。

たとえば、Josuttis と Vandevoorde のよく参照される (そして頼りになる) テンプレートに関する本、C++ Templates: The Complete Guideは傑出した本ですが、その本でさえ、テンプレートを含む各構文要素の厳密な用語を明確に識別していません。代わりに、意味は文脈から明らかです。

次の簡単な例を考えてみてください。これは、テンプレートに関連する 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) の場合、テンプレートの特殊化の状況があり、ペアが山かっこのが2 回<>現れるため、これら 2 つの非常に異なる山かっこのペアの山かっこの間に現れるパラメーター (引数?) を示すために使用される識別子には、分類上の区別が必要です。テンプレートのインスタンス化(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 に答える