检测类型是否为“映射" [英] Detect if type is a "mapping"

查看:28
本文介绍了检测类型是否为“映射"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用它们的 ::iterator 成员类型将 c++ 容器解析为另一个对象.迭代器成员类型指向单一类型对象(向量、队列等)的容器将变成类列表对象,迭代器成员类型指向std::pair的容器将变成一个类似地图的对象.

I'd like to parse c++ containers into another object using their ::iterator member type. Containers who's iterator member type points to an object of a single type (vectors, queues, etc.) will turn into a list-like object, and containers who's iterator member type points to an std::pair will turn into a map-like object.

我正在尝试编写一个成员函数来检测后一种容器,但它不起作用.这是我到目前为止所拥有的:

I'm trying to write a member function to detect the latter kind of container, but it does not work. Here's what I have so far:

#include <tuple>
#include <iterator>
#include <type_traits>

template <typename T>
struct is_pair : std::false_type { };

template <typename T, typename U>
struct is_pair<std::pair<T, U>> : std::true_type { };

template <typename T>
constexpr bool is_pair_v = is_pair<T>::value;

template <typename...>
struct is_mapping : std::false_type { };

template <typename Container>
struct is_mapping<Container, std::enable_if_t<
    is_pair_v<std::iterator_traits<typename Container::iterator>::value_type>
>> : std::true_type { };

template <typename T>
constexpr bool is_mapping_v = is_mapping<T>::value;

#include <map>
#include <vector>
#include <iostream>

int main() {
    std::cout << "is_pair:" << std::endl;
    std::cout << "Map:    " << is_pair_v<std::iterator_traits<std::map<int, int>::iterator>::value_type> << std::endl;
    std::cout << "Vector: " << is_pair_v<std::iterator_traits<std::vector<int>::iterator>::value_type>   << std::endl;
    std::cout << std::endl;
    std::cout << "is_mapping:" << std::endl;
    std::cout << "Map:    " << is_mapping_v<std::map<int, int>> << std::endl;
    std::cout << "Vector: " << is_mapping_v<std::vector<int>>   << std::endl;
}

出于某种原因,is_mapping_v 始终为假,代码结果如下:

For some reason, is_mapping_v is always false and the code results in this output:

$ g++ -std=c++14 temp.cc && ./a.out
is_pair:
Map:    1
Vector: 0

is_mapping:    
Map:    0
Vector: 0

我的代码有什么问题?

注意:这不是 检查类型是否为地图.该问题的答案使用 ::key_type::mapped_type 成员来检测映射(对于 std::multimap 等类失败>).我还在我的代码中明确使用了迭代器指向 std::pair 的事实,因此检查它更有意义.

Note: This is not the a duplicate of Checking if a type is a map. The answer to that question uses the ::key_type and ::mapped_type members to detect the map (It fails for classes such as std::multimap). I am also explicitly using the fact that the iterator points to std::pairs later in my code, so checking that makes a lot more sense.

推荐答案

is_pair_v<std::iterator_traits<typename Container::iterator>::value_type>

应该

is_pair_v<typename std::iterator_traits<typename Container::iterator>::value_type>

因为 value_type 是一种类型.如果没有 typename,它将被解析为一个值并且使 enable_if 失败,从而回退到主模板.

because value_type is a type. Without the typename, it will be parsed as a value and fail the enable_if, thus falling back to the primary template.

您在 main 中的测试产生正确值的原因是因为那里的模板已经实例化并且 value_type 是类型还是值没有歧义.

The reason your tests in main yield the correct value is because the templates there have already been instantiated and there is no ambiguity whether value_type is a type or value.

第二个错误是您的主要模板

The second error is your primary template

template<typename...>

应该是

template<typename, typename = void>

否则,is_mapping 永远不会是具有两个参数的特化,因为参数计数不匹配.

Otherwise, is_mapping<T> will never be the specialization with two arguments because the argument count mismatch.

直播

这篇关于检测类型是否为“映射"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆