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
Post a Comment