C++ 从可变参数推导迭代器类别

C++ 从可变参数推导迭代器类别,c++,c++11,variadic-templates,iterator-traits,C++,C++11,Variadic Templates,Iterator Traits,如何填写? 模板结构itr_类别{typedef/*?*/type;} 因此,type是最专业的iterator\u traits::iterator\u category…,它支持所有的Itrs”操作,如果没有单一的此类类别,则会失败(如enable\u if::type) Most specialized是指以下继承中最下级的类型(iterator\u category): struct input_iterator_tag { }; struct output_iterator_tag {

如何填写

模板结构itr_类别{typedef/*?*/type;}

因此,
type
是最专业的
iterator\u traits::iterator\u category…
,它支持所有的
Itrs
”操作,如果没有单一的此类类别,则会失败(如
enable\u if::type

Most specialized是指以下继承中最下级的类型(
iterator\u 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\u category
之类的东西就会失败


注意:这是一个不同于
std::iterator\u traits
中定义的层次结构(参见24.3或):这里
前向迭代器标签
来自
输入迭代器标签
输出迭代器标签
,而不仅仅是前者。这与SGI文档中描述的继承相对应(参见)。如果这个差异是相关的(顺便说一句,这是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;
};
templateclass f,typename init,typename。。。类型>
类褶皱;
模板class f,typename init>
结构折叠{
typedef初始化类型;
};
模板类f,typename初始化,typename类型参数,typename。。。类型_args>
结构折叠{
typedef typename fold::type,type_args…>::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;
};
模板
结构组合迭代器{
私人:
typedef typename迭代器:类别c1;
typedef typename迭代器:类别c2;
typedef decltype(false?(c1*)nullptr:(c2*)nullptr)ptype;
公众:
typedef typename std::decay::type类型;
};
模板结构itr\U类别{
typedef typename fold::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 *")
it1类;
模板结构迭代器特征{
typedef双向迭代器标记类别;
};
it2类;
模板结构迭代器特征{
typedef输入\迭代器\标记类别;
};
it3级;
模板结构迭代器特征{
typedef输出\迭代器\标记类别;
};
itr_类别::类型x;//typeid(x).name()=“结构输入\u迭代器\u标记”
itr_类别::类型y;//typeid(x).name()=“结构输出\u迭代器\u标记”
itr_类别::类型z;//操作数类型不兼容(“输入\迭代器\标记*”和“输出\迭代器\标记*”)
itr_类别:类型w;//操作数类型不兼容(“输入\迭代器\标记*”和“输出\迭代器\标记*”)

也许
std::common\u type
std::add\u reference
可以做到这一点?你可以在
type\u traits
中使用
std::common\u type
而不是
decltype(false?x:y)
-它做同样的事情,但是更干净。@JohannesD是的,如果你的编译器/库支持它的话。它与GCC一起工作,但在MSVC2010+ICC下似乎不起作用。