Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/151.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
检测类型是否为“a”;映射“; < >我想用它们的:迭代器< /代码>成员类型将C++容器解析成另一个对象。迭代器成员类型的容器指向单一类型的对象(向量、队列等)将变成类似列表的对象,迭代器成员类型的容器指向std::pair将变成类似映射的对象_C++_Template Meta Programming - Fatal编程技术网

检测类型是否为“a”;映射“; < >我想用它们的:迭代器< /代码>成员类型将C++容器解析成另一个对象。迭代器成员类型的容器指向单一类型的对象(向量、队列等)将变成类似列表的对象,迭代器成员类型的容器指向std::pair将变成类似映射的对象

检测类型是否为“a”;映射“; < >我想用它们的:迭代器< /代码>成员类型将C++容器解析成另一个对象。迭代器成员类型的容器指向单一类型的对象(向量、队列等)将变成类似列表的对象,迭代器成员类型的容器指向std::pair将变成类似映射的对象,c++,template-meta-programming,C++,Template Meta Programming,我试图编写一个成员函数来检测后一种容器,但它不起作用。以下是我目前掌握的情况: #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::p

我试图编写一个成员函数来检测后一种容器,但它不起作用。以下是我目前掌握的情况:

#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;
}
我的代码有什么问题



注意:这不是的副本。该问题的答案使用
::key_type
::mapped_type
成员来检测映射(对于
std::multimap
之类的类,它会失败)。我还显式地使用了这样一个事实,即迭代器在我的代码后面指向
std::pair
s,因此检查它更有意义。

编译器没有选择部分专用的结构。原因有两个:

  • 如果
    is\u pair\u v
    关闭,则执行
    启用。编译器会将
    std::iterator\u traits::value\u type
    视为一个值,而不是一个类型,但是SFINAE会起作用,它只是被悄悄地删除
  • 使用
    模板
    使其不被选择。如果我是对的,这是因为
    is_mapping
    可以使用初始定义解析为
    is_mapping
    ,或者使用专门化解析为
    is_mapping
    。在这种情况下,
    是首选的映射

    修复此问题与将其更改为
    模板一样简单:

  • 基本上,你的版本看起来像

    if (is_pair(...)) return true;
    else return false;
    
    而你只需要

    return is_pair(...)
    
    应该是

    template<typename, typename = void>
    
    模板
    
    否则,
    is_mapping
    将永远不会是具有两个参数的专门化,因为参数计数不匹配


    即使有了这个修复,这仍然不起作用:@Justin你说得对,忘了提到我修复了主模板,哦,对于没有
    ::迭代器成员类型的类型,更简单的实现不起作用。可能是
    
    if (is_pair(...)) return true;
    else return false;
    
    return is_pair(...)
    
    is_pair_v<std::iterator_traits<typename Container::iterator>::value_type>
    
    is_pair_v<typename std::iterator_traits<typename Container::iterator>::value_type>
    
    template<typename...>
    
    template<typename, typename = void>