0

私が書いたテンプレート疎行列クラスに STL スタイルの反復子がありますYaleStorage<D>。私は、異なる可能性operator==のある 2 つの行列を比較できるようにする行列クラスを作成しました。D

私のイテレータはテンプレートでもあるためconst_iterator、 とiteratorの特殊化としてiterator_T<RefType>、と のRefTypeいずれかを指定できconst D&ますD&

D異なる場合でも、これらのイテレータを比較できるようにする必要があります。異なるために constness を特に必要としconst_iteratorません ( a を an と比較する必要はありませんiterator)。operator!=などを書いた方法は次のとおりです。

template <typename D>
class YaleStorage {
  template <typename RefType>
  class iterator_T {
    template <typename E, typename ERefType = typename enable_if_else<std::is_const<RefType>::value, const E&, E&>::type>
    bool operator!=(const typename YaleStorage<E>::template stored_diagonal_iterator_T<ERefType>& rhs) const { /* some comparison code */ }
  };
  typedef iterator_T<D&>       iterator;
  typedef iterator_T<const D&> const_iterator;

  const_iterator cbegin() const { /* returns a const_iterator */ }
  const_iterator cend() const { /* returns the end const_iterator */ }
};

enable_if_elseSTL で同様の関数を見つけることができなかったので、自分で を作成したことに注意してください。これがそれです:

template <bool B, typename TA, typename TB>
struct enable_if_else {};
template <typename TA, typename TB>
struct enable_if_else<true, TA, TB> {  typedef TA type; };
template <typename TA, typename TB>
struct enable_if_else<false, TA, TB> { typedef TB type; };

残念ながら、通常の反復子比較 ( where ) を実行しようとするとD=E、次のような大量のエラーが発生します。

compiling ../../../../ext/nmatrix/storage/yale.cpp
../../../../ext/nmatrix/storage/yale.cpp: In instantiation of ‘VALUE nm::yale_storage::each_stored_with_indices(VALUE) [with DType = unsigned char; VALUE = long unsigned int]’:
../../../../ext/nmatrix/storage/yale.cpp:1686:3:   required from here
../../../../ext/nmatrix/storage/yale.cpp:1567:83: error: no match for ‘operator!=’ in ‘d != nm::YaleStorage<D>::cend() const [with D = unsigned char; nm::YaleStorage<D>::const_iterator = nm::YaleStorage<unsigned char>::iterator_T<const unsigned char&>]()’
../../../../ext/nmatrix/storage/yale.cpp:1567:83: note: candidates are:
In file included from ../../../../ext/nmatrix/storage/yale.cpp:64:0:
../../../../ext/nmatrix/storage/yale.h:438:10: note: template<class E, class ERefType> bool nm::YaleStorage<D>::iterator_T::operator!=(const typename nm::YaleStorage<E>::iterator_T<ERefType>&) const [with E = E; ERefType = ERefType; RefType = const unsigned char&; D = unsigned char]
../../../../ext/nmatrix/storage/yale.h:438:10: note:   template argument deduction/substitution failed:
../../../../ext/nmatrix/storage/yale.cpp:1567:83: note:   couldn't deduce template parameter ‘E’

結果を明示的にキャストしようとしたcend()ので、比較の両側に何があるかがわかりますが、なぜこれが詰まるのかわかりません。

template <typename DType>
static VALUE each_with_indices(VALUE nm) {
  YaleStorage<DType> y(s);

  // The next line is 1567:
  for (typename YaleStorage<DType>::const_iterator d = y.cbegin(); d != y.cend()); ++d) {
    /* Do some stuff with d */
  }
}

関数以外のテンプレート パラメーターを明示的に指定する方法は知ってoperatorいますが、演算子に対してはどのようにすればよいですか? 別のより良いアプローチはありますか?ここに何があるかは、コンパイラにとって明らかであるべきだと私には思えEます。

4

0 に答える 0