簡體   English   中英

C ++可變參數的可變參數模板參數

[英]C++ variadic number of variadic template parameters

有一個可變參數模板簡單,我可以專注它,所以它只能接受一個TStringConstant這是一個string_constant的一些char S:

template <typename TStringConstant, typename TValue>
class entry;

template <char... key, typename TValue>
class entry<string_constant<key...>, TValue>{}

如果我想創建一個模板類來接受不同char的可變數量的TStringConstant ,那么有沒有辦法做到這一點? 也許有模板模板參數?

這樣所有以下內容都是有效的:

entry_list<string_constant<'c','b','a'>, string_constant<'d','e','f','g'>>();
entry_list<string_constant<'c','b','a'>, string_constant<'d','e','f','g'>, string_constant<'d','e','z','z'>>();
entry_list<string_constant<'a','b','c'>>();

獎金,如果它將拒絕entry_list<something_else<'c','b','a'>>就像entry<something_else<'c','b','a'>, bool>將無法編譯。

你可以使用static_assert來完成它。 我不知道如何以友好的方式實現它,但我想你不關心這一點。

所以這里:

template <class... Args> struct entry {
    static_assert(are_string_constant<Args...>::value, "invalid template args for entry");
};

auto test()
{
  entry<string_constant<'c', 'd'>> e1; // OK
  entry<string_constant<'c', 'd'>, string_constant<'a', 'b', 'c', 'd'>> e2; // OK

  // entry<int,
  //       string_constant<'c', 'd'>,
  //       string_constant<'a', 'b', 'c', 'd'>> e3; // static_assert kicks in

  // entry<definitely_not_string_constant<'c', 'd'>,
  //       string_constant<'a', 'b', 'c', 'd'>> e4; // static_assert kicks in


}

are_string_constant的構建非常簡單:

template <char... Args> struct string_constant {};
template <char... Args> struct definitely_not_string_constant {};

// --- is_string_constant -----

template <class T> struct is_string_constant : std::false_type {};

template <char... Args>
struct is_string_constant<string_constant<Args...>> : std::true_type {};

// --- are_string_constant -----    

template <class... Args> struct are_string_constant;

template <class A0, class... Args>
struct are_string_constant<A0, Args...>
     : std::integral_constant<bool, (is_string_constant<A0>::value &&
                                     are_string_constant<Args...>::value)>::type
{};

template <class T> struct are_string_constant<T> : is_string_constant<T>::type {};

在c ++ 17中,使用折疊表達式可以更容易地實現(因為您不需要are_string_constant ):

template <class... Args>
struct entry {
    static_assert((... && is_string_constant<Args>::value),
                  "invalid template args for entry");
};

我看到的真正問題是:你想如何使用entry_list類的entry_list列表?

我喜歡bolov的解決方案(+1)但是,如果你接受遞歸解決方案,我建議使用繼承。

以下是一個完整的例子

template <char ...>
struct string_constant
 { };

template <char ...>
struct something_else
 { };

template <typename ...>
class entry_list;

template <>
class entry_list<>
 { };

template <char ... keys, typename ... Scs>
class entry_list<string_constant<keys ...>, Scs ...>
   : public entry_list<Scs ...>
 { };

int main ()
 {
   entry_list<string_constant<'c','b','a'>,
              string_constant<'d','e','f','g'>>(); // compile

   entry_list<string_constant<'c','b','a'>,
              string_constant<'d','e','f','g'>,
              string_constant<'d','e','z','z'>>(); // compile

   entry_list<string_constant<'a','b','c'>>(); // compile

   //entry_list<something_else<'c','b','a'>>(); // compilation error

   //entry_list<string_constant<'c','b','a'>, bool>(); // compilation error
 }

如果您不想使用繼承,則可以使用static_assert() ,如下所示

template <char ... keys, typename ... Scs>
class entry_list<string_constant<keys ...>, Scs ...>
 { static_assert(sizeof(entry_list<Scs...>), "!"); };

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM