4

私はこのコードを持っていて、理解したいです:

template <unsigned...>
struct sum;

template<unsigned size>
struct sum<size>
{
    enum {value = size};
};

template<unsigned size, unsigned... sizes>
struct sum<size, sizes...>
{
    enum { value = size + sum<sizes...>::value }; 
};

int _tmain(int argc, _TCHAR* argv[])
{
    sum<1, 2>::value;
    return 0;
}

実装されていない合計 (符号なしを取る...最後の構造体の特殊化と同じように、競合はありませんか?) がまったく存在しなければならない理由と、テンプレート部分から同じパラメーターを使用して合計を特殊化する方法がわかりませんe.g. sum<size, sizes...>( template <unsigned size, sizes...>. ベローが動かないのはなぜですか?

template<unsigned size>
struct sum
{
    enum {value = size};
};

template<unsigned size, unsigned... sizes>
struct sum
{
    enum { value = size + sum<sizes...>::value; }; 
};
4

3 に答える 3

8

構文が少し異なることに注意してください。プライマリ テンプレートを宣言すると、次のようになります。

template <unsigned...>
struct sum;

の後にテンプレート パラメータを指定しませんsum。これは、まったく新しいテンプレートを作成し、任意の数の符号なし整数をパラメーターとして受け取ると言っているためです。

これを行っているとき:

template<unsigned size, unsigned... sizes>
struct sum<size, sizes...>
{
    enum { value = size + sum<sizes...>::value }; 
};

前に宣言したテンプレートを特殊化しています。パラメータが符号なしの値で構成され、その後に任意の数の他の符号なしの値が続く場合、この定義を使用すると言っています。これは、プライマリ テンプレートとまったく同じではありません。プライマリ テンプレートには、パラメータが 0 の可能性があります。

これをしようとすると:

template<unsigned size>
struct sum
{
    enum { value = size };
};

template<unsigned size, unsigned... sizes>
struct sum // OOPS! A template called `sum` has already been declared!
{
    enum { value = size + sum<sizes...>::value }; 
};

同じ名前で 2 つの異なるクラス テンプレートを作成しようとしていますが、これは許可されていません。

これは、関数テンプレートの動作とは少し異なることに注意してください。関数テンプレートを使用すると、オーバーロードを行うことができるため、同じ名前の関数テンプレートが複数あっても問題ありません。ただし、関数テンプレートでは、部分的な特殊化を行うことはできません。これにより、多くのあいまいさが生じるためです。

プライマリ テンプレートとスペシャライゼーションの間にあいまいさがあると思うかもしれませんが、より専門的なスペシャライゼーションは常に、それほど専門的でないスペシャライゼーションよりも優先され、プライマリ テンプレートは常に最も専門化されていないと見なすことができます。これが正しくない場合、部分的な特殊化はまったく機能しません。

于 2013-09-07T18:21:59.007 に答える
0

最初の宣言:

template<unsigned int... Ns>
struct sum;

前方宣言: テンプレートを、可変数のunsigned intパラメーターを持つテンプレートとして宣言します。

最初の特殊化はメタ関数の基本ケースであり、バリアディック パックが 1 つのパラメーターのみを持つケースを保持します。

template<unsigned size>
struct sum<size>
{
    enum {value = size};
};

2 番目の特殊化は再帰的なケースです: variadic-pack に少なくとも 1 つのパラメーターがある場合を保持します。

template<unsigned size, unsigned... sizes>
struct sum<size, sizes...>
{
    enum { value = size + sum<sizes...>::value }; 
};

テンプレート メタ プログラミングを作成/学習する前に、C++ テンプレート メカニズム (インスタンス化、テンプレートの特殊化など) について詳しく学習することをお勧めします。

于 2013-09-07T18:24:25.010 に答える