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?
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>;
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;