My assignment is to make a multimap_util template class that helps the using of multimap. My main problem is that the multimap_util class should also work with custom sorted multimaps.
I don't know how to make it work with two different templates.
So with 2 template args like this:
std::multimap<int, int> m;
multimap_util<int, int> mu( m );
and with 3 template args like this:
std::multimap<std::string, std::string, string_size_more> lmm;
multimap_util<std::string, std::string, string_size_more> lmmu( lmm );
Here is my code:
template <typename T1, typename T2, typename C>
class multimap_util
{
std::multimap<T1, T2, C>* map;
public:
multimap_util(std::multimap<T1,T2>& map) : map(&map)
{};
multimap_util(std::multimap<T1,T2,C>& map) : map(&map)
{};
.
.
.
}
I always get errors like this:
error: wrong number of template arguments (2, should be 3)
66 | multimap_util<std::string, std::string> langsu( langs );
It has to be done without variadic template.
I red about template partial specialization but I don't know how it works. I also thought about making a child class with a different template that derives from the util class?
Take in count that std::multimap
has ever 4 template parameter. But with a default for the third and the fourth template parameter.
It seems to me that the best you can do is emulate the std::multimap
signature that is
template<
class Key,
class T,
class Compare = std::less<Key>,
class Allocator = std::allocator<std::pair<const Key, T> >
> class multimap;
you could write your class as follows
template <typename K, typename V,
typename C = std::less<K>,
typename A = std::allocator<std::pair<K const, V>>>
class multimap_util
{
private:
std::multimap<K, V, C, A>* map;
public:
multimap_util (std::multimap<K, V, C, A> & m) : map{&m}
{};
};
This works with
std::multimap<int, int> m;
multimap_util<int, int> mu( m );
because it's equivalent to
std::multimap<int, int, std::less<int>, std::allocator<std::pair<int const, int>> m;
multimap_util<int, int, std::less<int>, std::allocator<std::pair<int const, int>> mu( m );
and works also when you declare a multimap_util
with 3 or 4 template parameter: are ever 4 but some of them can be defaulted.
Unfortunately you can't use C++17 or C++20 because starting from C++17 is available CTAD (Class Template Argument Deduction) so you can also write
std::multimap<int, int> m;
multimap_util mu( m ); // <-- CTAD at works
and all template parameters, for multimap_utils
, are deduced from the m
argument.
To simplify your life, also in C++11 you can write a make_multimap_util()
function as follows
template <typename K, typename V, typename C, typename A>
multimap_util<K, V, C, A> make_multimap_util (std::multimap<K, V, C, A> & m)
{ return {m}; }
so, using the power of the auto
placeholder, you can simply write
std::multimap<int, int> m;
auto mu = make_multimap_util(m);
and mu
become a multimap_util<int, int>
or, its the same thing, multimap_util<int, int, std::less<int>, std::allocator<std::pair<int const, int>>
.