2

で 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 を実装する必要があると思います。

  • Incrementable 型のcounting_iterator、
  • または、エラーが示すように、私の Incrementable 型の場合 (これは意味がありますか?私の Incrementable 型イテレータではありません)。

ドキュメント (このトピックは完全に省略されています) からもどちらも明確ではなく、ライブラリの他の部分でそれに関する情報を見つけることができません。

boost::detailそこで、名前空間に次を追加しました。

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

これで、すべてがコンパイルされ、期待どおりに動作します。それでも、ライブラリがこのように使用されることを意図していたかどうかは本当に疑わしい.

これを実装する適切な/クリーンな方法を知っている人はいますか?

Steve Jessop の提案:専門化std::numeric_limitsも機能します:

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

これがインクリメンタル型に対して正しいことかどうかはまだわかりません。

4

1 に答える 1

4

あなたが言うように、Boostが「インクリメント可能な型」を定義しているかどうかはわかりません。あなたが言うようにそれを定義する場合、ドキュメントのバグがありcounting_iteratorます.「任意のインクリメント可能な型」で機能するとは言えません.それらはすべての要件ではないからです. あるいは、「テンプレートの他のパラメータを正しく指定すれば」というのは言うまでもありません。

Incrementableのテンプレート パラメータの要件は、counting_iteratorリンク先のドキュメントに記載されています (「iterator_categoryis defined as following...」から始まります。これは、実際の要件セクションが を参照しているためですiterator_category)。

特化すべきではありませんboost::detail::is_numeric。あなたは専門化する必要がありstd::numeric_limitsます。しかし、あなたの例では、Tあなたのタイプが数値であると主張するには、実際にはインターフェイスを狭めすぎていると思います(算術はありません)。CategoryOrTraversalタイプが数値でもイテレータでもない場合は、 asを指定することになっていると思いますforward_iterator_tag。私は何かを逃したかもしれません。

于 2013-08-02T16:21:28.533 に答える