#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: Для чего используется ключевое слово templatetypename
?
Ответ №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