元函数,缺少特征的默认行为以及如何检测随机访问

时间:2016-02-26 04:31:05

标签: c++ c++11 metaprogramming

以下元函数计算给定类型是否为随机访问迭代器:

    template <class I>
    struct is_random_access
        : boost::is_convertible
        < typename boost::iterator_traversal<I>::type
        , boost::random_access_traversal_tag
        >
    {};

当然,如果I根本不是迭代器,这不起作用,因为没有定义boost::iterator_traversal<I>

两个独立的问题:

  1. is_random_access不是迭代器时,如何使I返回false(而不是编译失败)?
  2. 这是检测迭代器是否可以随机访问的好方法吗?

1 个答案:

答案 0 :(得分:2)

对于第一个问题,您实际上可以使用SFINEA example from wikipedia

template <class... Ts> using void_t = void;

template <class I, class = void>
    struct is_random_access: boost::false_type
    {};

template <class I>
    struct is_random_access<I,void_t<typename std::iterator_traits<I>::iterator_category> >
        : boost::is_convertible
        <typename boost::iterator_traversal<I>::type, boost::random_access_traversal_tag>
    {};

如果输入类型没有定义iterator_category类型,它将回退到默认结构,如果已定义,它将使用您的专业化。

对于第二个问题,我不是专家。但是,我的解释与您同意:对于std::random_access_iterator_tag的每个迭代器,boost::iterator_traversal<>::type都可以转换为boost::random_access_traversal_tag

更新:修复了int *未被重新识别为有效迭代器的问题。将I:iteratory_category替换为std::iterator_traits<I>::iterator_category