Newsgroup: it.comp.lang.c++
Titolo: dubbio su const_reverse_iterator

Stò cercando di inizializzare un iteratore inverso costante...
Voglio inizializzarlo con il valore rbegin() di un container *non* costante:
	std::vector<std::string>* pvSource = &vecA; 
	std::vector<std::string>::const_reverse_iterator srcIt = pvSource->rbegin(); 
L'inizializzazione, per ragioni misterione, causa l'errore di compilazione:
'initializing' : cannot convert from 'type1' to 'type2'
dove 'type1' è il tipo di pvSource->rbegin() e 'type2' è quello di srcIt.
L'errore di compilazione si risolve se rendo pvSource puntatore a costante:
	const std::vector<std::string>* pvSource = &vecA; 
Nella STL, per vector e per gli altri contenitori, non dovrebbe essere implementato 
	// un operatore di conversione in reverse_iterator verso const_reverse_iterator
	reverse_iterator::operator const_reverse_iterator() const;
o alternativamente 
	// un costruttore copia di const_reverse_iterator da reverse_iterator
	const_reverse_iterator::const_reverse_iterator(const reverse_iterator&)
o qualcos'altro di equivalente?
Chi sbaglia???
- io?
- l'implementazione della STL?
- il compilatore?
_______________________________________
 Luca Minudel   Consulente Informatico
 
luca.m...@nline.it
 Conegliano (TV)
 WWW    
http://www.nline.it/consulting

 - il compilatore?
Manlio Perillo

 > - il compilatore?
Il dubbio quindi mi resta.
Chi sbaglia???


 Chi sbaglia???
A questo punto credo sia probabile che sbagli l'implementazione
della STL.
Comunque dovresti dire che compilatore usi.
Inoltre, se ti è possibile, dovresti vedere se nel reverse_iterator
è presente il costruttore di copie template.
Manlio Perillo

 
Non c'è nessun copy constructor. Solo il constructor di default ed un constructor che accetta come parametro un const_iterator.


 qualcosa.
Se usi il VC++ allora la colpa è del compilatore :-).
Non so se il VC++ 6 supporta questo, prova:
template<class T> class complex
{
   private:
      T re_, im_;
   public:
      template<class U> friend class complex;
      complex(const T& r, const T& i)
      : re_(r), im_(i) {  }
      // se complex<U> non è friend, other.re_ e other.im_ sono
      // inaccessibili
      template<class U> complex(const complex<U>& other)
      : re_(other.re_), im_(other.im_) {  }
};
int main()
{
   complex<int> ci(3, 4);
   complex<float> cf = ci;
}
Il costruttore template serve proprio a questo.
Tuttavia per usarlo, il compilatore deve supportare sia i
membri template che i friend template.
Per i vari problemi che ho incontrato con i template,
se ti interessa vedi il mio post: "problemi con template").
Riguardo alla 'conversione' fra iterator in const_iterator,
lo Standard è coerente.
Infatti ho provato:
#include <list>
typedef std::list< std::list<int> > llist;
int main()
{
   llist lA;
   llist* pvSource = &lA;
   llist::const_reverse_iterator srcIt = pvSource->rbegin();
   llist::const_iterator citer = pvSource->begin();
}
(Uso list perchè l'iteratore è user-defined).
Fra i costruttori di list::const_iterator c'è anche quello
che accetta un list::iterator.
Se non ricordo male, tempo fa su comp.lang.c++.moderated,
c'era stato un thread proprio su questo.
Forse Nicola Musatti può dirci qualcosa di più...
Manlio Perillo

 
Ogni suggerimento è gradito!
Ciao


 che davvero lo standard preveda tale conversione?
Sia nel BCC 5.5 che nel KAI C++ e nel DJGPP il costruttore di copie
template è presente.
Per concludere è presente anche nella descrizione che lo Stroustrup
fa nel suo libro (19.2.5).
Quindi credo ci siano pochi dubbi che tale cosa sia prevista dallo
Standard.
Manlio Perillo

 fa nel suo libro (19.2.5).
Ho guardato al cap. 19.2.5  di C++ prog. lang. 3rd ed. ma ho trovato solo il costruttore copia che accetta const reverse_iterator (che può coincidere con i const_reverse_iterator per una implementazione ma è decisamente un tipo differente).
Se ho sbagliato, puoi indicarmi meglio dove guardare? 
Grazie. Ciao


 Se ho sbagliato, puoi indicarmi meglio dove guardare?
Nel libro che possiedo io (6th ristampa) il costruttore di copie
'normale' non è presente (è lasciato quello di default), mentre
è presente il costruttore:
template<Class Iter> class reverse_iterator....
{
    protected:
        Iter current;
    public:
        template<class U>
        reverse_iterator(const reverse_iterator<U>& x)
        : current(x.base()) {  }
        Iter base() const { return current; }
        // ...
};
Manlio Perillo