Von Indexiteratoren und Threads die mit Von beginnen
-
Heute eine Schwemme von mir, entschuldigung

Ich habe im Schweiße meines Angesichts einen folgenden Iterator geschrieben:
struct default_tag {}; template< typename ReferenceType, typename PointerType, typename Tag, typename SizeType = std::size_t > struct do_dereference { static ReferenceType dereference( PointerType obj_, SizeType index_ ) { return obj_->dereference( index_, Tag() ); } }; template< typename ReferenceType, typename PointerType, typename SizeType > struct do_dereference< ReferenceType, PointerType, default_tag, SizeType > { static ReferenceType dereference( PointerType obj_, SizeType index_ ) { return obj_->dereference( index_ ); } }; template< typename ValueType, typename FriendClass, bool IsConst, typename Tag = default_tag, typename SizeType = std::size_t > class index_iterator : public boost::iterator_facade< index_iterator< ValueType, FriendClass, IsConst, Tag, SizeType >, typename std::conditional< IsConst, const ValueType, ValueType >::type, std::random_access_iterator_tag > { private: typedef Tag tag_type; typedef SizeType size_type; friend FriendClass; public: typedef typename std::conditional< IsConst, const FriendClass*, FriendClass* >::type pointer_type; typedef SizeType size_type; index_iterator( pointer_type object, size_type index ) : object_( object ), index_( index ) { } index_iterator( const index_iterator& other ) { object_ = other.object_; index_ = other.index_; } public: reference dereference() { return do_dereference<reference,pointer_type, tag_type>::dereference( object_, index_ ); } const reference dereference() const { return do_dereference<const reference,pointer_type, tag_type>::dereference( object_, index_ ); } void increment() { ++index_; } void decrement() { --index_; } void advance( size_type off ) { index += off; } bool equal( const index_iterator& other ) const { assert( object_ == other.object_ ); return index_ == other.index_; } difference_type distance( index_iterator& other ) const { return index_ - other.index_; } operator index_iterator< ValueType, FriendClass, true, Tag, SizeType >() const { return index_iterator< ValueType, FriendClass, true, Tag, SizeType >( object_, index_ ) } private: pointer_type object_; size_type get_index() const { return index_; } size_type index_; };Sodass folgendes Minimalbeispiel funktioniert:
class my_vector { public: typedef utility::index_iterator< double, my_vector, false > iterator; typedef utility::index_iterator< double, my_vector, true > const_iterator; iterator begin() { return iterator( this, 0 ); } iterator end() { return iterator( this, vec_.size() ); } double& dereference( std::size_t index ) { return vec_[index]; } private: std::vector< double > vec_; };Jetzt meine Fragen:
- Gibts sowas schon? Sinnlos?
- Werden die nutzlosen Tag-Argumente vom Compiler wegoptimiert?Viele Grüße,
Deci
-
Beschreibe in WORTEN was dein Gebilde sein soll und welches Problem geloest werden muss!
-
Nun, ich dachte es erschließt sich aus der Beispielklasse da unten.
Diese index_iterator-Klasse ist dazu gedacht, eine Iterator-Sequenz über irgendwas zu bauen, das nicht "direkt da" ist. Also irgendwelche Temp-Objekte oder ähnliches, die aber ansonsten semantisch Random-Accessible sind. Ein Beispiel wäre zum Beispiel (wer sollte es glauben) ein Reihen-Iterator, der intern über einem std::vector< std::vector< some > > läuft, wobei hier die innere Dimension einer Spalte entspricht. Es gibt also nicht direkt Reihen, aber man kann dennoch einen Wrapper für sowas basteln. So, und hier kommt der index_iterator ins Spiel, man entwickelt einen Reihen-Wrapper, implementiert eine dereference-Methode mit oder ohne Tag-Argument (besser mit, wegen Typsicherheit), macht noch einen typedef und ist fertig. Man muss sich also nicht mehr einen pseudo-iterator basteln.Viele Grüße,
Deci