gpt4 book ai didi

c++ - 消除类 map 容器和类 vector 容器之间的模板特化

转载 作者:IT老高 更新时间:2023-10-28 22:19:54 26 4
gpt4 key购买 nike

template<class> struct Printer;

// I want this to match std::vector (and similar linear containers)
template<template<class, class...> class T, class TV, class... TS>
struct Printer<T<TV, TS...>> { ... };

// I want this to match std::map (and similar map-like containers)
template<template<class, class, class...> class TM, class TK, class TV, typename... TS>
struct Printer<TM<TK, TV, TS...>> { ... }

int main()
{
// Both of these match the second specialization, which is only intended
// for std::map (and similar map-like containers)
Printer<std::vector<int>>::something();
Printer<std::map<int, float>>::something();
}

从示例中可以看出,std::vectorstd::map 都匹配第二个特化。我认为这是因为 std::vector 的分配器参数与 TV 匹配,该参数用于 std::map 的值。

如何将 std::vector (和其他线性容器) 与第一个特化和 std::map 匹配(和其他键值容器) 与第二个?

最佳答案

模式匹配方法的问题在于,它只有在为每个容器编写一个专门化的情况下才有效。这是一项乏味的工作。

相反,您可以依赖其他属性:

  • 容器必须可以通过 begin(c)end(c) 表达式进行迭代
  • 除此之外,关联容器将具有 ::key_type 嵌套类型等,如 § 23.2.4 [associative.rqmts] 中所述。

因此,我们可以根据标签调度创建一个分类器:

inline constexpr auto is_container_impl(...) -> std::false_type {
return std::false_type{};
}

template <typename C>
constexpr auto is_container_impl(C const* c) ->
decltype(begin(*c), end(*c), std::true_type{})
{
return std::true_type{};
}

template <typename C>
constexpr auto is_container(C const& c) -> decltype(is_container_impl(&c)) {
return is_container_impl(&c);
}

inline constexpr auto is_associative_container_impl(...)
-> std::false_type
{ return std::false_type{}; }

template <typename C, typename = typename C::key_type>
constexpr auto is_associative_container_impl(C const*) -> std::true_type {
return std::true_type{};
}

template <typename C>
constexpr auto is_associative_container(C const& c)
-> decltype(is_associative_container_impl(&c))
{
return is_associative_container_impl(&c);
}

现在你可以编写“简单”的代码了:

template <typename C>
void print_container(C const& c, std::false_type/*is_associative*/) {
}

template <typename C>
void print_container(C const& c, std::true_type/*is_associative*/) {
}

template <typename C>
void print_container(C const& c) {
return print_container(C, is_assocative_container(c));
}

现在,这可能不是你想要的,因为在这个要求下,set 是一个关联容器,但它的值不是 pair,所以你无法打印 key: value。您必须根据需要调整标签调度。

关于c++ - 消除类 map 容器和类 vector 容器之间的模板特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21660325/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com