代码之家  ›  专栏  ›  技术社区  ›  Parker

std::map::size_类型用于值_类型为其自身大小_类型的std::map

  •  4
  • Parker  · 技术社区  · 5 年前

    我有一个 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;
    

    让编译器推断正确代码的正确方法是什么 value_type 暂时 std::map 谁的 这是它自己的 size_type

    7 回复  |  直到 5 年前
        1
  •  1
  •   Max Langhof    5 年前

    一般来说,你要找的是不可能的。

    这是可以想象的(尽管牵强) std::map<int, long>::size_type int std::map<int, int>::size_type long std::map<int, T>::size_type 存在 T

    相反,也可能是这样 标准::地图<int,T>::尺寸和类型 定义为 T T 满足你的“要求”。

    正如几个答案(以及您自己的参考链接)所提到的,实际上,除了 size_t .

        2
  •  6
  •   felix    5 年前

    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 是相同的(成员) 类型 别名 尺寸和类型
        3
  •  4
  •   Quentin    5 年前

    免责声明:此解决方案相当愚蠢。我们将通过反复(通常是一次)尝试实例化来解决这个方程 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

        4
  •  2
  •   Acorn    5 年前

    使用 std::size_t . 无符号整数 std::map::size_type 标准:尺寸

    如果要确定,请断言它:

    static_assert(std::is_same_v<
        std::size_t,
        std::map<std::string, std::size_t>::size_type
    >);
    
        5
  •  2
  •   Parker    5 年前

    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);
    

    如果(合理的)假设失败,这只会导致编译错误。

        6
  •  1
  •   Toby Speight    5 年前

    打破循环依赖关系的唯一方法是使用特定类型。我建议你简单地 map_index std::size_t C++强大 implies 那是 标准:尺寸 map::size_type .

        7
  •  1
  •   max66    5 年前

    size_type 属于 std::map

    如果是这样,我看不出有什么办法。

    但是 尺寸和类型 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");