如何填写???
template<class...Itrs> struct itr_category { typedef /* ??? */ type; };
这样type
是iterator_traits<Itrs>::iterator_category...
中最专业的它支持所有 Itrs
' 操作,否则如果没有单个此类类别,则会失败(如 enable_if<false>::type
)?
最专业表示以下继承中最下降的类型( iterator_category
):
struct input_iterator_tag { };
struct output_iterator_tag { };
struct forward_iterator_tag : public input_iterator_tag,
public output_iterator_tag { };
struct bidirectional_iterator_tag : public forward_iterator_tag { };
struct random_access_iterator_tag : public bidirectional_iterator_tag { };
例如,类似 itr_category<InputIterator,OutputIterator,...>
的内容会失败。
注意:这是一个与 std::iterator_traits
中定义的不同的层次结构(参见 24.3 或 http://en.cppreference.com/w/cpp/iterator/iterator_tags ):这里 forward_iterator_tag
源自 input_iterator_tag
和output_iterator_tag
,而不仅仅是前者。这对应于 SGI 文档中描述的继承(参见 http://www.sgi.com/tech/stl/Iterators.html )。如果相关的话,请随意评论此差异(顺便说一下,这是 zip 迭代器实现的一部分)。
最佳答案
首先,您需要一个用于类型的 fold
函数,如下所示:
template< template< typename, typename > class f, typename init, typename... types >
class fold;
template< template< typename, typename > class f, typename init >
struct fold< f, init > {
typedef init type;
};
template< template< typename, typename > class f, typename init, typename type_arg, typename... type_args >
struct fold< f, init, type_arg, type_args... > {
typedef typename fold< f, typename f< init, type_arg >::type, type_args... >::type type;
};
然后,定义一个组合函数:
template< typename i1, typename i2 >
struct combine_iterators {
private:
typedef typename iterator_traits< i1 >::category c1;
typedef typename iterator_traits< i2 >::category c2;
typedef decltype( false ? ( c1 * )nullptr : ( c2 * )nullptr ) ptype;
public:
typedef typename std::decay< decltype( *( ptype )nullptr ) >::type type;
};
template<class...Itrs> struct itr_category {
typedef typename fold< combine_iterators, random_access_iterator_tag, Itrs... >::type type;
};
基本上就是这样:
class it1;
template<> struct iterator_traits< it1 > {
typedef bidirectional_iterator_tag category;
};
class it2;
template<> struct iterator_traits< it2 > {
typedef input_iterator_tag category;
};
class it3;
template<> struct iterator_traits< it3 > {
typedef output_iterator_tag category;
};
itr_category< it1, it2 >::type x; // typeid( x ).name() == "struct input_iterator_tag"
itr_category< it1, it3 >::type y; // typeid( x ).name() == "struct output_iterator_tag"
itr_category< it2, it3 >::type z; // operand types are incompatible ("input_iterator_tag *" and "output_iterator_tag *")
itr_category< it1, it2, it3 >::type w; // operand types are incompatible ("input_iterator_tag *" and "output_iterator_tag *")
关于c++ - 从可变参数推导迭代器类别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11772019/