c++ - How to parameterize the number of parameters of a constructor? -


i want accept number of parameters (this number being defined in template parameter) in template class constructor. can't use initializer_list, since can't assert size @ compile time, far know.

what tried

my first attempt using std::array parameter:

template<size_t s> class foo {   int v[s]; public:   foo(std::array<int, s>) {/*...*/} }; 

however, forces me initialize (even when constructor not explicit) :

foo<4> a{{1,2,3,4}} // 2 brackets. 

i think there may template magic (variadic templates?), can't figure out proper syntax use in constructor. can't call constructor recursively... can i?

i tried looking definition of constructor std::array(since doesn't allow more parameters size of array, want), find has implicit constructors. default constructors? if so, how does

std::array<int, 3> = {1,2,3} 

work?

optional bonus: why didn't standard define fixed size alternative std::initializer_list? std::static_initializer_list<t, n>. there plans on supporting kind of functionality in future? needed?

you create variadic constructor , assert provided right number of arguments:

template <size_t sz> struct foo {     template <typename... args>     foo(args... args) {         static_assert(sizeof...(args) <= sz, "invalid number of arguments");         // ... stuff ...     } }; 

so that:

foo<3> f;                // ok foo<3> f(1, 2, 3);       // ok foo<3> f(1, 2, 3, 4, 5); // error 

as example initialize array, like:

template <size_t sz> struct foo {     template <typename... args>     foo(args... args)      : v{{args...}}     {         static_assert(sizeof...(args) <= sz, "invalid number of arguments");     }      std::array<int, sz> v; }; 

that constructs v correctly you'd expect, though if try pass more sz args foo's constructor, you'd see error on initializing v before static_assert.

for clearer static_assert error, delegate top-level foo private constructors take integral_constant argument whether or not they're valid constructors:

template <typename... args> foo(args... args) : foo(std::integral_constant<bool, sizeof...(args) <= sz>{},        args...) { }  private: template <typename... args> foo(std::true_type, args... args) : v{{args...}} { }  template <typename false, typename... args> foo(false, args... ) {      // false ever std::false_type     static_assert(false::value, "invalid number of arguments!"); } 

Comments

Popular posts from this blog

PHP DOM loadHTML() method unusual warning -

python - How to create jsonb index using GIN on SQLAlchemy? -

c# - TransactionScope not rolling back although no complete() is called -