5

このようにパラメータパックの最初の要素を取得することが可能です

template <typename... Elements>
struct type_list
{
};

template <typename TypeList>
struct type_list_first_element
{
};

template <typename FirstElement, typename... OtherElements>
struct type_list_first_element<type_list<FirstElement, OtherElements...>>
{
    typedef FirstElement type;
};

int main()
{
   typedef type_list<int, float, char> list;
   typedef type_list_first_element<list>::type element;
   return 0;
}

しかし、このような最後の要素を同様に取得することはできません

template <typename... Elements>
struct type_list
{
};

template <typename TypeList>
struct type_list_last_element
{
};

template <typename LastElement, typename... OtherElements>
struct type_list_last_element<type_list<OtherElements..., LastElement>>
{
    typedef LastElement type;
};

int main()
{
   typedef type_list<int, float, char> list;
   typedef type_list_last_element<list>::type element;
   return 0;
}

gcc 4.7.1で不平を言う:

エラー: 'struct type_list_last_element<type_list<int, float, char>>' の 'type' に型の名前がありません

標準のどのパラグラフがこの動作を説明していますか?

テンプレート パラメーター パックは、一致するすべての引数を消費するという意味で貪欲であるように思われます。この場合、OtherElementsは 3 つの引数 ( intfloatおよびchar) をすべて消費し、何も残っていないLastElementため、コンパイルは失敗します。私は仮定で正しいですか?

編集:

明確にするために:パラメーターパックから最後の要素を抽出する方法を尋ねているのではなく、その方法を知っています。私が実際に望んでいるのは、前面ではなく背面からパックを選択することです。そのため、各要素の背面までずっと再帰することは効果がありません。明らかに、シーケンスを事前に逆にすることが最も賢明な選択です。

4

2 に答える 2

4

関連する節は、14.5.5:8 の最後の箇条書きです。

14.5.5 クラス テンプレートの部分的な特殊化 [temp.class.spec]

8 - クラス テンプレートの部分的な特殊化の引数リスト内では、次の制限が適用されます: [...]

  • 引数には、展開されていないパラメーター パックを含めてはなりません。引数がパック展開 (14.5.3) の場合、それはテンプレート引数リストの最後の引数になります。
于 2012-09-19T15:36:28.693 に答える
1

観察:

  1. の最後の要素は、が空でない 場合のみ<first,...>の最後の要素と同じです。<...>...
  2. 1 つの要素リストの最後の要素<elem>elem

したがって、tail テンプレートを使用して、再帰的に実行する必要があります。

再帰:

template <typename TypeList>
struct type_list_last_element;

template <typename FirstElement, typename... OtherElements>
struct type_list_last_element<type_list<FirstElement, OtherElements...>>
{
    typedef typename type_list_last_element<type_list<OtherElements...>>::type type;
};

しっぽ:

template <typename LastElement>
struct type_list_last_element<type_list<LastElement>>
{
    typedef LastElement type;
};

[更新]そして使用法:

int main()
{
   typedef type_list<int, float, char> list;
   typedef type_list_last_element<list>::type last;
   return 0;
}

[更新終了]

イデオンを見る

于 2012-09-18T19:38:43.677 に答える