Указание параметра шаблона с помощью Typedef

#c #templates #iterator #c 11

#c #шаблоны #итератор #c 11

Вопрос:

Я хочу иметь возможность передавать два объединенных итератора как один, чтобы использовать преимущества некоторых алгоритмов, подобных stl (таких как TBB), поэтому я создаю пользовательский итератор, который объединяет их, но наталкиваюсь на некоторые камни преткновения.

Мне нужно специализировать итератор, однако он не позволит мне в общем случае указать параметр шаблона.

Вот так:

 template<typename IT1, typename IT2>
struct multi_iter : public std::iterator<
                            std::output_iterator_tag,
                            std::pair<IT1::value_typeamp;, IT2::value_typeamp;> >
{
.
:
  

Однако это позволит мне сделать это, но это не то, что мне нужно

 template<typename IT1, typename IT2>
struct multi_iter : public std::iterator<
                            std::output_iterator_tag,
                            std::pair<intamp;, intamp;> >
{
.
:
  

Я получаю эту ошибку

 multi_iter.cpp:12:53: error: template argument 2 is invalid
multi_iter.cpp:12:55: error: template argument 2 is invalid
multi_iter.cpp:12:55: error: template argument 4 is invalid
multi_iter.cpp:12:55: error: template argument 5 is invalid
.
:
  

У меня есть std::pair

Буду признателен за любую помощь.

Спасибо

Комментарии:

1. Вы не специализируетесь std::iterator . Вы должны написать весь свой класс итератора с нуля.

2. уточните, пожалуйста: я должен отметить, что это работает точно так, как должно, когда я указываю целые числа

3. @KerrekSB, на самом деле, вы можете специализироваться std::iterator , чтобы получить несколько удобных определений типов: cplusplus.com/reference/std/iterator/iterator . Однако вы должны предоставить все реализации функций.

4. KerrekSB: приведенный выше пример кода был сокращен, чтобы сохранить его актуальность, я реализовал все функции, требуемые output_iterator

Ответ №1:

value_type является зависимым типом от IT1 , поэтому вы должны указать typename там

 typename IT1::value_type
  

Комментарии:

1. Где он специализируется на чем-либо?

2. Я бы хотел, чтобы мой компилятор мог сказать мне об этом : : S. Но спасибо, что решил это: D

3. @111111 : Для объяснения того, почему typename это необходимо, и как узнать, когда его использовать, см. Этот FAQ: Для чего используется ключевое слово template typename ?

Ответ №2:

Вы пробовали это?

 template<typename IT1, typename IT2>
struct multi_iter : public std::iterator<
                            std::output_iterator_tag,
                            std::pair< typename IT1::value_typeamp;, typename IT2::value_typeamp; > >
{
.
:
  

Ответ №3:

 template<typename IT1, typename IT2>
struct multi_iter : public std::iterator<
                            std::output_iterator_tag,
                            std::pair<IT1::value_typeamp;, IT2::value_typeamp;> >
  

IT1::value_type зависит от параметра типа и является типом, поэтому его необходимо обозначить typename ключевым словом:

 template<typename IT1, typename IT2>
struct multi_iter : public std::iterator<
                            std::output_iterator_tag,
                            std::pair<typename IT1::value_typeamp;, typename IT2::value_typeamp;> >
  

Кстати, если вы хотите «сжать» два итератора (то есть выполнить итерацию двух последовательностей {1, 2} и {«a», «b»}, как (1, «a»), затем (2, «b»)), взгляните на zip_iterator избиблиотека boost.iterators.

Комментарии:

1. Спасибо, я посмотрю на zip_iterator, я действительно искал что-то подобное. Хотя TBH это работает сейчас, и разборка показывает, что он полностью компилируется: D