为什么重建的地图类型与原始地图类型不同?

Why is a re-constructed map type different from the original one?

本文关键字:地图 类型 原始 重建 为什么      更新时间:2023-10-16

请考虑以下代码:

#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::value_typestd::pair<const Key, Value>,而不是std::pair<Key, Value>。 原因是永远不允许修改映射中对的键。

要使用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;

testmap::value_type::first_typeconst int而不是int

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

正如其他人所指出的,这:

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

...不太正确,因为const会自动添加到键中以用于value_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