2

どうすれば記入できますか???

template<class...Itrs> struct itr_category { typedef /* ??? */ type; };

だから、それはすべての'操作をサポートするtype最も専門的なものです、そうでなければ、そのようなカテゴリが1つもない場合の失敗(のような)?iterator_traits<Itrs>::iterator_category...Itrsenable_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両方から派生しています。これは、たとえばSGIドキュメント( http://www.sgi.com/tech/stl/Iterators.htmlを参照)で説明されている継承に対応します。関連する場合は、この不一致についてコメントしてください(ちなみに、これはzipイテレータの実装の一部です)。input_iterator_tagoutput_iterator_tag

4

2 に答える 2

1

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 *")
于 2012-08-02T07:32:00.223 に答える
1

common_category最小値を生成する特性を定義するだけです。次に、タイプをのタイプとして定義しますcommon_category<firstiter, common_category<seconditer, etc>>。そのようなものの可変個引数テンプレートの指示を忘れています。

于 2012-08-02T06:52:53.490 に答える