Is it possible to do mixing of types and nontypes in variadic template parameters? If I were to pass a std::array
for instance to this class as parameter T
, I would need to also pass a type for the array and a length, but the way I tried it below causes an error when encountering a value, because it only expects types for Types
:
template <
template<class, std::size_t> class T,
class ... Types>
class C {
T<Types...> storage;
};
int main(){
C<std::array, int, 3> c;
}
Error message:
error: template argument for template type parameter must be a
type
Container<std::array, int, 3> c;
^
Is there a way to pass types and values in a variadic context?
Args declares an "object parameter" (pass by value) and Args&& declares a reference parameter (pass by reference). Passing by reference allows one to avoid copying the argument when that is unnecessary.
With the variadic templates feature, you can define class or function templates that have any number (including zero) of parameters. To achieve this goal, this feature introduces a kind of parameter called parameter pack to represent a list of zero or more parameters for templates.
Variadic templates are class or function templates, that can take any variable(zero or more) number of arguments. In C++, templates can have a fixed number of parameters only that have to be specified at the time of declaration.
Parameter packs (C++11) A parameter pack can be a type of parameter for templates. Unlike previous parameters, which can only bind to a single argument, a parameter pack can pack multiple parameters into a single parameter by placing an ellipsis to the left of the parameter name.
Is it possible to do mixing of types and nontypes in variadic template parameters?
No. You can't mix and match. But since you can wrap a value in a type but not the other way around, you can just stay in the world of types:
template <template<class...> class T, class ... Types>
class C {
T<Types...> storage;
};
And then it's just a matter of making std::array
work with just types:
template <class T, class N>
using my_array = std::array<T, N::value>;
template <size_t N>
using size_ = std::integral_constant<size_t, N>;
So your original example becomes:
C<my_array, int, size_<3>> c;
As I see, you alreadty hardcoded the number and types of parameter the class T
must take as template parameter. You don't need variadic templates here. Just do this instead:
template <
template<class, std::size_t> class T,
class A, std::size_t N>
class C {
T<A, N> storage;
};
int main(){
C<std::array, int, 3> c; // works!
}
If you wish to use variadic templates, then put it in the template template parameter too:
template <
template<typename...> class T,
typename... Types>
class C {
T<Types...> storage;
};
If you wish to use that version but still want to use std::array
, you can create an alias to std::array
that already has a size:
template<typename T>
using array3 = std::array<T, 3>;
C<array3, int> c;
Alternatively, you can also create some sort of template template alias that let you choose the size:
template<std::size_t n>
struct sized_array {
template<typename T>
using array = std::array<T, n>;
};
C<sized_array<5>::array, int>;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With