Nested C++ template parameters for functions
c++, c++11, templates
Solution
`std::vector` has two parameters, type and allocator. Try this
template <typename T, typename Alloc, template <typename, typename> class V>
void print_container(V<T, Alloc> &con)
{
}
print_container(vec);
This will work for `vector`, `list`, etc., but will not work with `map`, `set`.
However, since you use `auto` you can use C++11 and then you can to this:
template <typename T, template <typename, typename...> class V, typename... Args>
void print_container(V<T, Args...> &con)
or
template <template <typename, typename...> class V, typename... Args>
void print_container(V<Args...> &con)
and of course most simple way is to do something like
template<typename C>
void print_container(C& con)
probably with some checks for deduce, that `C` is really container.
template<typename C>
auto print_container(C& con) -> decltype(con.begin(), void())
Problem
I want to have a templated function in C++, where one template parameter is itself a template of another template parameter. If that doesn't make any sense, take the following code that prints a std::vector that is templated on type T ``` template <typename T> void print_vector(std::vector<T> &vec) { for(auto v: vec) std::cout << v << " "; std::cout << std::endl; } ... std::vector<double> vec(5); ... print_vector(vec); ``` I want to further generalize this function for STL containers other than `vector`. But I don't know how to "nest" the template parameters such that the container is templated on type T. I have tried the following with no success ``` template <typename T, template <typename TT> V> void print_container(V<T> &con) { for(auto c: con) std::cout << c << " "; std::cout << std::endl; } ... std::vector<double> vec(5); ... print_container(vec); ``` I am sure this has been answered here before, but I can't find the search terms to find the answer. Thanks @ForEveR. Your response was right on the money! All of the responses to my question observed that there is no need have the "storage" type T templated, with the following solution being adequate for the example I gave: ``` template <typename C> void print_container(C &con) { for(auto v: con) std::cout << v << " "; std::cout << std::endl; } ``` Unfortunately, the actual use case that motivated the question was a little bit more complicated. The routine takes multiple containers, like this linear algebra example with a matrix and vector class: ``` template <typename MATRIX, typename VECTOR> void mat_vec_multiply(const MATRIX &A, const VECTOR &x, VECTOR &y) { // Implement y = A*x; } ``` Assume that both the MATRIX and VECTOR classes have to be templated on the same underlying storage class (i.e., `double`, `float`, `int`, etc.). The idea is that by explicitly specifying T as a template parameter, we can enforce this: ``` template < typename T, template<typename> class MATRIX, template<typename> class VECTOR> void mat_vec_multiply(const MATRIX<T> &A, const VECTOR<T> &x, VECTOR<T> &y) { // Implement y = A*x; } ``` Unfortunately, I am using the CUDA compiler nvcc, which doesn't have any support for C++11 constructs (I just used C++11 in my example because it is less verbose). So I can't use `std::is_same` and `static_assert`, though I suppose I could roll my own `is_same` (or use Boost) easily enough. What is the "best practice" in this case, where I want to enforce the common template parameter for the storage classes?