4

可変長テンプレートを持つことは簡単で、それが唯一のいくつかのchar秒のstring_constantあるTStringConstantを受け入れるように私はそれを特化することができますパラメータ異なるcharTStringConstantの可変数を受け入れるテンプレートクラスは、それを行う方法がありますか?おそらく、テンプレートテンプレートのパラメータですか?C++可変引数の数は

次のすべてが有効になるように:それはコンパイルに失敗しますentry_list<something_else<'c','b','a'>>だけentry<something_else<'c','b','a'>, bool>のように拒否されます

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'>>(); 

ボーナス場合。

答えて

3

static_assertで行うことができます。私はsfinaeフレンドリーな方法でそれを実装する方法を知らないが、私はあなたがそれを気にしないと思います。

だからここには行く:

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の建物はかなり単純です:

C++ 17では
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 {}; 

実装がfold expressions(なぜなら、あなたドンと簡単ですare_string_constantが必要です):

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

実際の問題は、entry_listクラスの可変文字リストをどのように使いたいのですか?

私はbolovの解(+1)が好きですが、再帰的解を受け入れるならば、継承の使用を提案します。

次はあなたが使用継承したくない場合は

template <char ... keys, typename ... Scs> 
class entry_list<string_constant<keys ...>, Scs ...> 
{ static_assert(sizeof(entry_list<Scs...>), "!"); }; 
を次のように、あなたの代わりに static_assert()を使用することができ、完全な例

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 
} 

です