2013-08-02 1 views
2

Я пытаюсь использовать Incrementable type с boost::counting_iterator.Использование boosting_iterator с добавочным типом

boost::counting_iteratordocumentation says, что итератор работает для возрастающих типов, то есть типов, которые являются CopyConstructible, Assignable, PreIncrementable и EqualityComparable. Тип

Мои Incrementable:

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 либо для :

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

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

Поэтому я добавил следующее 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; 
}; 
} 

Тем не менее, я не знаю, если это то, что нужно сделать для incrementable типа.

ответ

4

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

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

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

 Смежные вопросы

  • Нет связанных вопросов^_^