std::map::size_type 对于 std::map 其 value_type 是它自己的 size_type
std::map::size_type for a std::map whose value_type is its own size_type
我有一个 std::map<std::pair<std::string, std::string>, float>
占用太多内存,为了使用更少的内存,我决定将唯一字符串映射到整数(例如,std::map<std::string, int>
,其中每个新的唯一字符串都映射到映射的当前 size()
),并使用这些整数值作为映射的成对键(例如,std::map<std::pair<int, int>, float>
)。
而不是 int
,我想使用 std::map::size_type:
using map_index = std::map::size_type;
std::pair<map_index, map_index> key;
当然,这不会编译,因为我需要为地图提供参数列表:
vector.cc:14:19: error: invalid use of template-name `std::map' without an argument list
using map_index = std::map::size_type;
这(理论上)是我想要实现的目标:
using map_index = std::map<std::string, map_index>::size_type;
它给出了以下(预期的)编译器错误:
vector.cc:15:41: error: `map_index' was not declared in this scope
using map_index = std::map<std::string, map_index>::size_type;
让编译器为 std::map
推断正确 value_type
的正确方法是什么,value_type
是它自己的 size_type
?
但是您确定 std::map
的 size_type
取决于 key/value 类型吗?
如果是这样,我找不到获取它的方法。
但是 size_type
不应该依赖于 key/value 类型,通常是 std::size_t
.
我建议
using Index0 = typename std::map<std::string, std::size_t>::size_type;
using mapIndex = typename std::map<std::string, Index0>::size_type;
您可以通过
检查您的类型是否正确
static_assert( std::is_same_v<Index0, mapIndex>, "no right type");
打破循环依赖的唯一方法是使用特定类型。我建议您只需将 map_index
设为 std::size_t
- C++ 强烈 implies 即可将 std::size_t
分配给 map::size_type
.
size_t
对于这种情况应该足够好了。
但如果你坚持,你可以这样做:
#include <type_traits>
#include <map>
template <class Key, class Value = size_t, size_t depth = 0, class = void>
struct GetSizeType {
using type = typename GetSizeType<Key, typename std::map<Key, Value>::size_type, depth + 1>::type;
};
template <class Key, class Value, size_t depth>
struct GetSizeType<Key, Value, depth, std::enable_if_t<std::is_same_v<Value, typename std::map<Key, Value>::size_type>>> {
using type = typename std::map<Key, Value>::size_type;
};
template <class Key, class Value>
struct GetSizeType<Key, Value, 100, void> {};
int main() {
using X = GetSizeType<int>::type;
return 0;
}
它将运行在GetSizeType
递归,递归调用将在
停止
- 达到递归调用深度限制(在这种情况下将没有成员
type
),或
- 找到
std::map
的特化,其中 mapped_type
和 size_type
相同(成员 type
别名为 size_type
)。
免责声明:这个解决方案非常愚蠢。我们只是要通过反复(通常一次)尝试实例化 std::map
来求解方程,直到我们找到一个具有请求的键和它自己的 size_type
作为值。
template <class T>
struct identity {
using type = T;
};
template <class K, class V = char>
struct auto_map {
using map_type = std::map<K, V>;
using type = typename std::conditional_t<
std::is_same_v<
typename map_type::mapped_type,
typename map_type::size_type
>,
identity<map_type>,
auto_map<K, typename map_type::size_type>
>::type;
};
template <class K>
using auto_map_t = typename auto_map<K>::type;
如果元函数找不到这样的映射,它会因为 type
最终定义为自身而出错,或者打破递归限制。
使用std::size_t
。无符号整数 std::map::size_type
不会大于 std::size_t
并且在实践中将是同一类型。
如果你想确定,断言:
static_assert(std::is_same_v<
std::size_t,
std::map<std::string, std::size_t>::size_type
>);
你要找的东西,一般来说是不可能的。
可以想象(虽然牵强附会)std::map<int, long>::size_type
是int
,std::map<int, int>::size_type
是long
(其他整数类型也类似),在这种情况下有不可能满足 std::map<int, T>::size_type
是 T
.
相反,对于所有 T
,std::map<int, T>::size_type
可能被定义为 T
,在这种情况下,没有唯一的 T
满足您的 "requirement".
正如几个答案(以及您自己的参考 link)所提到的,在实践中它不太可能是 size_t
.
我使用过的所有 C++ 实现都对所有地图使用相同大小的类型。
所以;
using map_size_type = std::map<int, int>::size_type;
using my_map = std::map<std::string, map_size_type>;
static_assert(std::is_same<map_size_type, my_map::size_type);
如果(合理的)假设失败,这只会导致编译错误。
我有一个 std::map<std::pair<std::string, std::string>, float>
占用太多内存,为了使用更少的内存,我决定将唯一字符串映射到整数(例如,std::map<std::string, int>
,其中每个新的唯一字符串都映射到映射的当前 size()
),并使用这些整数值作为映射的成对键(例如,std::map<std::pair<int, int>, float>
)。
而不是 int
,我想使用 std::map::size_type:
using map_index = std::map::size_type;
std::pair<map_index, map_index> key;
当然,这不会编译,因为我需要为地图提供参数列表:
vector.cc:14:19: error: invalid use of template-name `std::map' without an argument list
using map_index = std::map::size_type;
这(理论上)是我想要实现的目标:
using map_index = std::map<std::string, map_index>::size_type;
它给出了以下(预期的)编译器错误:
vector.cc:15:41: error: `map_index' was not declared in this scope
using map_index = std::map<std::string, map_index>::size_type;
让编译器为 std::map
推断正确 value_type
的正确方法是什么,value_type
是它自己的 size_type
?
但是您确定 std::map
的 size_type
取决于 key/value 类型吗?
如果是这样,我找不到获取它的方法。
但是 size_type
不应该依赖于 key/value 类型,通常是 std::size_t
.
我建议
using Index0 = typename std::map<std::string, std::size_t>::size_type;
using mapIndex = typename std::map<std::string, Index0>::size_type;
您可以通过
检查您的类型是否正确static_assert( std::is_same_v<Index0, mapIndex>, "no right type");
打破循环依赖的唯一方法是使用特定类型。我建议您只需将 map_index
设为 std::size_t
- C++ 强烈 implies 即可将 std::size_t
分配给 map::size_type
.
size_t
对于这种情况应该足够好了。
但如果你坚持,你可以这样做:
#include <type_traits>
#include <map>
template <class Key, class Value = size_t, size_t depth = 0, class = void>
struct GetSizeType {
using type = typename GetSizeType<Key, typename std::map<Key, Value>::size_type, depth + 1>::type;
};
template <class Key, class Value, size_t depth>
struct GetSizeType<Key, Value, depth, std::enable_if_t<std::is_same_v<Value, typename std::map<Key, Value>::size_type>>> {
using type = typename std::map<Key, Value>::size_type;
};
template <class Key, class Value>
struct GetSizeType<Key, Value, 100, void> {};
int main() {
using X = GetSizeType<int>::type;
return 0;
}
它将运行在GetSizeType
递归,递归调用将在
- 达到递归调用深度限制(在这种情况下将没有成员
type
),或 - 找到
std::map
的特化,其中mapped_type
和size_type
相同(成员type
别名为size_type
)。
免责声明:这个解决方案非常愚蠢。我们只是要通过反复(通常一次)尝试实例化 std::map
来求解方程,直到我们找到一个具有请求的键和它自己的 size_type
作为值。
template <class T>
struct identity {
using type = T;
};
template <class K, class V = char>
struct auto_map {
using map_type = std::map<K, V>;
using type = typename std::conditional_t<
std::is_same_v<
typename map_type::mapped_type,
typename map_type::size_type
>,
identity<map_type>,
auto_map<K, typename map_type::size_type>
>::type;
};
template <class K>
using auto_map_t = typename auto_map<K>::type;
如果元函数找不到这样的映射,它会因为 type
最终定义为自身而出错,或者打破递归限制。
使用std::size_t
。无符号整数 std::map::size_type
不会大于 std::size_t
并且在实践中将是同一类型。
如果你想确定,断言:
static_assert(std::is_same_v<
std::size_t,
std::map<std::string, std::size_t>::size_type
>);
你要找的东西,一般来说是不可能的。
可以想象(虽然牵强附会)std::map<int, long>::size_type
是int
,std::map<int, int>::size_type
是long
(其他整数类型也类似),在这种情况下有不可能满足 std::map<int, T>::size_type
是 T
.
相反,对于所有 T
,std::map<int, T>::size_type
可能被定义为 T
,在这种情况下,没有唯一的 T
满足您的 "requirement".
正如几个答案(以及您自己的参考 link)所提到的,在实践中它不太可能是 size_t
.
我使用过的所有 C++ 实现都对所有地图使用相同大小的类型。
所以;
using map_size_type = std::map<int, int>::size_type;
using my_map = std::map<std::string, map_size_type>;
static_assert(std::is_same<map_size_type, my_map::size_type);
如果(合理的)假设失败,这只会导致编译错误。