问题描述
我的任务是制作一个 multimap_util 模板类,帮助使用 multimap。 我的主要问题是 multimap_util 类也应该与自定义排序的多重映射一起使用。
我不知道如何让它与两个不同的模板一起工作。
所以有 2 个这样的模板参数:
std::multimap<int,int> m;
multimap_util<int,int> mu( m );
并使用 3 个模板参数,如下所示:
std::multimap<std::string,std::string,string_size_more> lmm;
multimap_util<std::string,string_size_more> lmmu( lmm );
这是我的代码:
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,C>& map) : map(&map)
{};
.
.
.
}
我总是收到这样的错误:
error: wrong number of template arguments (2,should be 3)
66 | multimap_util<std::string,std::string> langsu( langs );
它必须在没有可变参数模板的情况下完成。
我对模板部分专业化感到不满,但我不知道它是如何工作的。 我还考虑过使用派生自 util 类的不同模板创建子类?
解决方法
考虑到 std::multimap
有曾经 4 个模板参数。但是第三个和第四个模板参数有一个默认值。
在我看来,您能做的最好的事情就是模拟 std::multimap
签名 that is
template<
class Key,class T,class Compare = std::less<Key>,class Allocator = std::allocator<std::pair<const Key,T> >
> class multimap;
你可以按如下方式编写你的类
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,A> & m) : map{&m}
{};
};
这适用于
std::multimap<int,int> m;
multimap_util<int,int> mu( m );
因为它等价于
std::multimap<int,int,std::less<int>,std::allocator<std::pair<int const,int>> m;
multimap_util<int,int>> mu( m );
并且在您声明带有 3 或 4 个模板参数的 multimap_util
时也有效:曾经是 4,但其中一些可以是默认值。
不幸的是你不能使用C++17或C++20,因为从C++17开始是可用的CTAD(类模板参数推导)所以你也可以写
std::multimap<int,int> m;
multimap_util mu( m ); // <-- CTAD at works
multimap_utils
的和所有模板参数是从 m
参数推导出来的。
为了简化您的生活,您也可以在 C++11 中编写一个 make_multimap_util()
函数,如下所示
template <typename K,typename C,typename A>
multimap_util<K,A> make_multimap_util (std::multimap<K,A> & m)
{ return {m}; }
因此,利用 auto
占位符的强大功能,您可以简单地编写
std::multimap<int,int> m;
auto mu = make_multimap_util(m);
和 mu
变成 multimap_util<int,int>
或者,它是同一个东西,multimap_util<int,int>>
。