更多的 C++ 模板?

问题描述

我的任务是制作一个 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>>