I am trying to write function which is roughly similar to a function that takes two instances of containers (let's say for now they are the same), containing same type and merges them. So here's my function for vectors:
template<typename T>
void test(std::vector<T> v1, std::vector<T> v2) {
std::cout << "called nested for c\n";
}
and it works.
Now I want to have one that would work for sets or vectors. And I try this:
template<typename T, template <typename> typename C >
void test(C<T> v1, C<T> v2) {
std::cout << "called nested for c<t>\n";
}
and get
nestedt.cc:33:6: note: template argument deduction/substitution failed: nestedt.cc:43:12: error: wrong number of template arguments (3, should be 1) test(s, s); ^ nestedt.cc:32:51: note: provided for ‘template class C’ template typename C > ^
I try
template< template <typename T> typename C >
void test(C<T> v1, C<T> v2) {}
std::set<int> s = {1,2};
test(s, s);
and that doesn't work:
nestedt.cc:32:6: note: template argument deduction/substitution failed: nestedt.cc:42:12: note: cannot convert ‘s’ (type ‘std::set’) to type ‘int’ test(s, s); ^
So I try
template<typename C, typename T >
void test(C<T> v1, C<T> v2) {}
and get
nestedt.cc:32:6: note: candidate: template void test(C, C) void test(C v1, C v2) { ^ nestedt.cc:32:6: note: template argument deduction/substitution failed: nestedt.cc:42:12: note: couldn't deduce template parameter ‘T’ test(s, s); ^
I feel like I'm not even close to understanding how templates actually work in C++ and it is so sad. Also in reality I want the containers to be different. And ideally be able to somehow specify a limited set of allowed containers. And they are not really std:: containers.
Note that the final goal is to be able to take 2 different containers, so something like test(vector<int>, set<int>). And modifying the containers is kind of impossible.
I believe what you are looking for is
template<template <typename...> typename Cont1,
template <typename...> typename Cont2,
typename... T>
void test(Cont1<T...> a, Cont2<T...> b) { }
In the above template <typename...> typename Cont1 declares one template template type and template <typename...> typename Cont2 declares another one so you can have two different container types. The both share T... so each template container needs to have a matching template parameter list. This means
test(std::map<int, int>{}, std::map<int, int>{});
test(std::set<int>{}, std::set<int>{});
test(std::vector<int>{}, std::set<int>{});
all work but
test(std::map<int, int>{}, std::vector<int>{});
test(std::map<int, int>{}, std::set<int>{});
wouldn't.
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