Использование boost counting_iterator с типом Incrementable

Я пытаюсь использовать инкрементный тип с boost::counting_iterator,

boost::counting_iterator документация говорит что итератор работает с типами Incrementable, то есть с типами CopyConstructible, Assignable, PreIncrementable и EqualityComparable.

Мой тип увеличения:

template<class T> struct Incrementable {
// CopyConstructible:
Incrementable() : value(0) {}
Incrementable(const Incrementable& other) : value(other.value) {}
explicit Incrementable(const T& other) : value(other) {}
// Assignable:
inline Incrementable& operator=(const Incrementable& other) {
value = other.value;
return *this;
}
// PreIncrementable:
inline Incrementable& operator++() {
++value;
return *this;
}
// EqualityComparable:
friend
inline bool operator==(const Incrementable& a, const Incrementable& b) {
return a.value == b.value;
}

T value;
};

Это не в состоянии скомпилировать:

#include <boost/iterator/counting_iterator.hpp>
#include "incrementable.h"int main() {
boost::counting_iterator<Incrementable<int>> a(Incrementable<int>(0));
return 0;
}

Ошибка:

usr/local/include/boost/iterator/iterator_categories.hpp:161:60: error: no type named 'iterator_category' in 'boost::detail::iterator_traits<Incrementable<int> >'
typename boost::detail::iterator_traits<Iterator>::iterator_category

Я предполагаю, что мне нужно реализовать iterator_category либо для:

  • counting_iterator моего инкрементного типа,
  • или, как говорится в ошибке, для моего типа Incrementable (имеет ли это смысл? мой тип Incrementable не является итератор).

Ни то, ни другое не ясно из документации (которая полностью исключает эту тему), и я не могу найти какую-либо информацию об этом в других частях библиотеки.

Поэтому я добавил следующее boost::detail Пространство имен:

namespace boost { namespace detail {
template <class T> struct is_numeric<Incrementable<T>>
: mpl::true_ {};
}} // boost::detail namespace

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

Кто-нибудь знает правильный / чистый способ реализации этого?

Предложение Стива Джессопа: специализация std::numeric_limits также работает:

namespace std {
template<class T>
class numeric_limits<Incrementable<T>> : public numeric_limits<T> {
public:
static const bool is_specialized = true;
};
}

Тем не менее, я не знаю, правильно ли это делать для инкрементного типа.

2

Решение

Я не уверен, что Boost определяет «тип с приращением», как вы говорите. Если он определяет это как вы говорите, то есть ошибка документации, это не должно сказать, что counting_iterator работает для «любого возрастающего типа», потому что это не все требования. Или я полагаю, что это правда, если «при условии, что вы правильно указали другие параметры шаблона», само собой разумеется.

Требования к Incrementable параметр шаблона для counting_iterator приведены в документе, на который вы ссылаетесь (начиная с «iterator_category определяется следующим образом … «, потому что фактический раздел требований относится к iterator_category).

Вы не должны специализироваться boost::detail::is_numeric, Вы должны специализироваться std::numeric_limits, Но в вашем примере, я думаю, вы на самом деле сузили интерфейс T слишком много, чтобы утверждать, что ваш тип числовой (у него нет арифметики). Если ваш тип не является ни числовым, ни итератором, я думаю, вы должны указать CategoryOrTraversal как forward_iterator_tag, Возможно, я что-то пропустил.

4

Другие решения

Других решений пока нет …