使用可变参数模板的多键映射

2024-04-02

我正在尝试使用 C++ 中的可变参数模板来实现具有不同访问键的映射。我想要得到的是使这样的语法起作用:

MultikeyMap<int, double, float> map1; // int and double are keys, float is value type 
map1[ 2 ] = 3.5;
map1[ 5.7 ] = 22;

MultikeyMap<unsigned long long, int, float, double, int> map2; // more keys, int is value type
map2[100000000000ULL] = 56;

// etc...

我现在拥有的看起来像:

template<class V, class... Krest>
class MultikeyMap;

template<class V, class K, class... Krest>
class MultikeyMap<V, K, Krest...> : protected std::map<K, V>,
                                    protected MultikeyMap<V, Krest...>
{
public:
    template<class T>
    void insert( const T& t, const V& v )
    {
        std::map<T, V>::insert( make_pair( t, v ));
    }

    template<class T>
    const V* find( const T& k )
    {
        typedef std::map<T,V> currentMap;
        currentMap::const_iterator it = currentMap::find( k );
        return it == currentMap::end() ? 0 : &it->second;
    }

};

template<class V>
class MultikeyMap<V>
{};

为了使代码简单,我没有在 insert 和 find 中返回迭代器。

我发现这个解决方案有两个主要缺陷。

First,值类型在模板参数列表中排在第一位。最初我尝试写

template<class K, class... Krest, class V>
class MultikeyMap<K, Krest..., V>

但编译器坚持认为“如果类模板部分特化的参数是包扩展,那么它应该是最后一个参数”.

Second是来自 std::maps 的受保护继承。我真的很想使用组合来代替它,但在这种情况下,我看不到访问存储的地图的方法。如果有一个静态_if,我会写

template<class V, class K, class... Krest>
class MultikeyMap<V, K, Krest...> : protected MultikeyMap<V, Krest...>
{
public:
    template<class T>
    void insert( const T& t, const V& v )
    {
        static if( is_same<T,K>::value )
            m_map.insert( make_pair( t, v ));
        else
            MultikeyMap<V, Krest...>::insert( t, v );
    }
private:
    std::map<K,V> m_map;
};

请针对我提到的问题提出建议。如果有更好的方法,我很乐意学习。

谢谢阅读。


更简单但不完全等效的方法可能是升压Bimap http://www.boost.org/doc/libs/1_42_0/libs/bimap/doc/html/index.html or 增强多索引 http://www.boost.org/doc/libs/1_54_0/libs/multi_index/doc/index.html.

前者是一个映射,其中键可以在其中查找值,反之亦然,而后者则更为通用:它是一个具有任意数量索引的容器,允许排序(“类似列表”)、随机访问(“矢量式”)、关联式(“地图式”)和散列访问。

您可以尝试将可变参数模板包装在 Boost.MultiIndex 周围,那么至少您不必重新实现所有插入/擦除逻辑(但仅是薄包装器)。

Note:Boost.MultiIndex 不需要类型的可变序列,您还可以使用成员函数的可变序列来提取用户定义类的各种数据成员作为主要数据类型。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用可变参数模板的多键映射 的相关文章

  • 检查两个数是否是彼此的排列?

    给定两个数字 a b 使得 1 例如 123 是 312 的有效排列 我也不想对数字中的数字进行排序 如果您指的是数字的字符 例如 1927 和 9721 则 至少 有几种方法 如果允许排序 一种方法是简单地sprintf将它们放入两个缓冲
  • 访问私人成员[关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 通过将类的私有成员转换为 void 指针 然后转换为结构来访问类的私有成员是否合适 我认为我无权修改包含我需要访问的数据成员的类 如果不道德 我
  • ASP.NET Core Serilog 未将属性推送到其自定义列

    我有这个设置appsettings json对于我的 Serilog 安装 Serilog MinimumLevel Information Enrich LogUserName Override Microsoft Critical Wr
  • 如何忽略“有符号和无符号整数表达式之间的比较”?

    谁能告诉我必须使用哪个标志才能使 gcc 忽略 有符号和无符号整数表达式之间的比较 警告消息 gcc Wno sign compare 但你确实应该修复它警告你的比较
  • Newtonsoft JSON PreserveReferences处理自定义等于用法

    我目前在使用 Newtonsoft Json 时遇到一些问题 我想要的很简单 将要序列化的对象与所有属性和子属性进行比较以确保相等 我现在尝试创建自己的 EqualityComparer 但它仅与父对象的属性进行比较 另外 我尝试编写自己的
  • C - 找到极限之间的所有友好数字

    首先是定义 一对友好的数字由两个不同的整数组成 其中 第一个整数的除数之和等于第二个整数 并且 第二个整数的除数之和等于第一个整数 完美数是等于其自身约数之和的数 我想做的是制作一个程序 询问用户一个下限和一个上限 然后向他 她提供这两个限
  • 如何将图像和 POST 数据上传到 Azure 移动服务 ApiController 终结点?

    我正在尝试上传图片and POST表单数据 尽管理想情况下我希望它是json 到我的端点Azure 移动服务应用 我有ApiController method HttpPost Route api upload databaseId sea
  • 指针减法混乱

    当我们从另一个指针中减去一个指针时 差值不等于它们相距多少字节 而是等于它们相距多少个整数 如果指向整数 为什么这样 这个想法是你指向内存块 06 07 08 09 10 11 mem 18 24 17 53 7 14 data 如果你有i
  • 在 ASP.NET Core 3.1 中使用包含“System.Web.HttpContext”的旧项目

    我们有一些用 Net Framework编写的遗留项目 应该由由ASP NET Core3 1编写的API项目使用 问题是这些遗留项目正在使用 System Web HttpContext 您知道它不再存在于 net core 中 现在我们
  • Github Action 在运行可执行文件时卡住

    我正在尝试设置运行google tests on a C repository using Github Actions正在运行的Windows Latest 构建过程完成 但是当运行测试时 它被卡住并且不执行从生成的可执行文件Visual
  • 如何衡量两个字符串之间的相似度? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 给定两个字符串text1 and text2 public SOMEUSABLERETURNTYPE Compare string t
  • 如何将单个 char 转换为 int [重复]

    这个问题在这里已经有答案了 我有一串数字 例如 123456789 我需要提取它们中的每一个以在计算中使用它们 我当然可以通过索引访问每个字符 但是如何将其转换为 int 我研究过 atoi 但它需要一个字符串作为参数 因此 我必须将每个字
  • Qt表格小部件,删除行的按钮

    我有一个 QTableWidget 对于所有行 我将一列的 setCellWidget 设置为按钮 我想将此按钮连接到删除该行的函数 我尝试了这段代码 它不起作用 因为如果我只是单击按钮 我不会将当前行设置为按钮的行 ui gt table
  • clang 实例化后静态成员初始化

    这样的代码可以用 GCC 编译 但 clang 3 5 失败 include
  • 如何在 VBA 中声明接受 XlfOper (LPXLOPER) 类型参数的函数?

    我在之前的回答里发现了问题 https stackoverflow com q 19325258 159684一种无需注册即可调用 C xll 中定义的函数的方法 我之前使用 XLW 提供的注册基础结构 并且使用 XlfOper 类型在 V
  • 如何使我的表单标题栏遵循 Windows 深色主题?

    我已经下载了Windows 10更新包括黑暗主题 文件资源管理器等都是深色主题 但是当我创建自己的 C 表单应用程序时 标题栏是亮白色的 如何使我自己的桌面应用程序遵循我在 Windows 中设置的深色主题 你需要调用DwmSetWindo
  • 控制到达非 void 函数末尾 -wreturn-type

    这是查找四个数字中的最大值的代码 include
  • C 中的异或运算符

    在进行按位操作时 我在确定何时使用 XOR 运算符时遇到一些困难 按位与和或非常简单 当您想要屏蔽位时 请使用按位 AND 常见用例是 IP 寻址和子网掩码 当您想要打开位时 请使用包含或 然而 XOR 总是让我明白 我觉得如果在面试中被问
  • 使用按位运算符相乘

    我想知道如何使用按位运算符将一系列二进制位相乘 但是 我有兴趣这样做来查找二进制值的十进制小数值 这是我正在尝试做的一个例子 假设 1010010 我想使用每个单独的位 以便将其计算为 1 2 1 0 2 2 1 2 3 0 2 4 虽然我
  • 恢复上传文件控制

    我确实阅读了以下帖子 C 暂停 恢复上传 https stackoverflow com questions 1048330 pause resume upload in c 使用 HTTP 恢复上传 https stackoverflow

随机推荐