具有缺失特征默认行为的元函数以及如何检测随机访问
meta function with default behavior on missing trait and how to detect random access
以下元函数计算给定类型是否为随机访问迭代器:
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>
。
两个独立的问题:
- 当
I
不是迭代器时,如何使 is_random_access
return 为假(而不是编译失败)?
- 这是检测迭代器是否可随机访问遍历的好方法吗?
对于你的第一个问题,你实际上可以使用 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
。
以下元函数计算给定类型是否为随机访问迭代器:
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>
。
两个独立的问题:
- 当
I
不是迭代器时,如何使is_random_access
return 为假(而不是编译失败)? - 这是检测迭代器是否可随机访问遍历的好方法吗?
对于你的第一个问题,你实际上可以使用 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
。