【问题标题】:Why is a re-constructed map type different from the original one?为什么重新构建的地图类型与原始地图类型不同?
【发布时间】:2020-03-11 18:27:56
【问题描述】:

考虑以下代码:

#include <iostream>
#include <typeinfo>
#include <map>


int main(int argc, const char* argv[]) {
    typedef std::map<int,float> testmap;
    typedef std::map<int,float> testmap2;
    typedef std::map<typename testmap::value_type::first_type, typename testmap::value_type::second_type> rebuiltMap;
    std::cout << "map samenes: " << std::is_same<testmap, rebuiltMap>::value << "\n";
    std::cout << "map samenes: " << std::is_same<testmap, testmap2>::value << "\n";
    std::cout << "original map type name " << typeid(testmap).name() << "\n";
    std::cout << "same     map type name " << typeid(testmap2).name() << "\n";
    std::cout << "rebuilt  map type name " << typeid(rebuiltMap).name() << "\n";
    std::cout << "original map valuetype " << typeid(testmap::value_type).name() << "\n";
    std::cout << "rebuilt  map valuetype " << typeid(rebuiltMap::value_type).name() << "\n";
}

这会产生以下输出:

map samenes: 0
map samenes: 1
original map type name St3mapIifSt4lessIiESaISt4pairIKifEEE
same     map type name St3mapIifSt4lessIiESaISt4pairIKifEEE
rebuilt  map type name St3mapIKifSt4lessIS0_ESaISt4pairIS0_fEEE
original map valuetype St4pairIKifE
rebuilt  map valuetype St4pairIKifE

为什么“重建”地图类型与简单地图类型不同,尽管两者具有相同的 value_type? 背景:我想测试包含对的容器是否是带有类似结构的地图

std::is_same<std::map<typename Container::value_type::first_type,
                      typename Container::value_type::second_type>,
             Container>::value

【问题讨论】:

  • 拆解的类型名称:std::map&lt;int, float, std::less&lt;int&gt;, std::allocator&lt;std::pair&lt;int const, float&gt; &gt; &gt; 和 std::map&lt;int const, float, std::less&lt;int const&gt;, std::allocator&lt;std::pair&lt;int const, float&gt; &gt; &gt;

标签: c++ types


【解决方案1】:

这是因为std::map::value_type 是std::pair&lt;const Key, Value&gt;,而不是std::pair&lt;Key, Value&gt;。这样做的原因是您永远不能修改映射中的一对键。

要使用value_type::first_type 使重建的地图相同,您需要使用std::remove_const_t 删除该const,例如

typedef std::map<std::remove_const_t<typename testmap::value_type::first_type>, typename testmap::value_type::second_type> rebuiltMap;

【讨论】:

    【解决方案2】:

    testmap::value_type::first_type 是 const int 而不是 int。

    您可以改用testmap::key_type 来获取正确的类型。基于对类型,无法区分 const 和非 const 键类型。也就是说,const 键不能满足 std::map 的要求,因此您可以简单地假设它是非常量的,然后从 testmap::value_type::first_type 中删除 const。

    【讨论】:

      【解决方案3】:

      正如其他人指出的那样:

      std::map<typename testmap::value_type::first_type, typename testmap::value_type::second_type>
      

      ... 不太正确,因为 const 会自动添加到密钥中以供在 value_type 和 this results in a distinct type 中使用。

      这就是 GCC 混乱的名字告诉你的:

      St3mapIKifSt4lessIS0_ESaISt4pairIS0_fEEE
      //     ^ const
      

      我的建议是使用 map 提供的方便的类型别名:

      std::map<typename testmap::key_type, typename testmap::mapped_type>
      

      ……或者,对于一个完整的解决方案:

      std::map<
         typename testmap::key_type,
         typename testmap::mapped_type,
         typename testmap::key_compare,
         typename testmap::allocator_type
      >
      

      毕竟,这就是别名的用途。 ?


      或者直接使用testmap!

      【讨论】:

      • 谢谢,这些答案解决了我的问题。 key_type 和 mapped_type 在我的情况下没有帮助,因为如果容器是例如a std::list<:pair>> 它们不存在,测试将失败。
      • @Dr.JürgenHannappel 但这是件好事!我实际上建议您只检查 mapped_type 的存在,以确定您的容器是否具有关联性,而不是您现在正在做的“重建”技巧。你的方式有太多的边缘情况和妥协。您无法可靠地取回“此value_type 属于地图”的信息。因此,应将模板代码构建为基于类型的特征和属性。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-12
      • 1970-01-01
      • 1970-01-01
      • 2011-08-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多