Newsgroup: it.comp.lang.c++
Titolo: std::vector

Come č possible creare un std::vector di std::vector? non dico
necessariemente nel caso generale piuttosto per esempio un std::vector di
std::vector<int>... Ho rpovato con una dichiarazione del tipo:
std::vector<std::vector<int>>
ma non compila.
(riesco a tranquillamente a creare un'array di vector ma un vector sarebbe
stato piů comodo)
grazie e ciao
Antonio

 Antonio
Come non compila? Deve compilare...che errore ti da il tuo compilatore?

 ma non compila.
Devi inserire almeno uno spazio fra > e >

> č un operatore, il parser lo interpreta cosě e va in tilt

 >> č un operatore, il parser lo interpreta cosě e va in tilt
Ottimo! grazie funziona!
Bye
Antonio

 >> č un operatore, il parser lo interpreta cosě e va in tilt
Didatticamente parlando :-) sottolinei un punto importante: in C++
bisognerebbe abituarsi a vedere ogni operatore, anche quelli piu' comuni
e insospettati, come oggetto.operator
Es.
int k(1);
int i = 2 + k;
equivale a:
int i.operator=(2.operator+(k));
Insomma, rispetto al C e' una bella perdita d'innocenza... -_^
Ciao
Gian Michele
--
Strane democrazie quelle in cui si uccidono i presidenti...

 int i.operator=(2.operator+(k));
In realtà potrebbe equivalere semmai a:
int i(2.operator+(k));
vedi copy-constructor...
Bye
Antonio

 Insomma, rispetto al C e' una bella perdita d'innocenza... -_^
Uhm... siamo sicuri che vedere le cose in quel modo sia del tutto
corretto?
EMG
--
EMAG Software Homepage:     
http://www.emagsoftware.it
The EMG's ZX-Spectrum Page: 
http://www.emagsoftware.it/spectrum
The Best of Spectrum Games: 
http://www.emagsoftware.it/tbosg

 ha scritto nel messaggio
news:Cz4da.12347$Fc.3...@tornado.fastwebnet.it...

Oh, giusto, grazie :-)
Gian Michele

 corretto?
Mi sembra di si' dal punto di vista di un possibile metodo di analisi:
tu cosa hai in mente?
Inoltre in caso di overloading ti rendi subito conto di come vengono
usati i tipi di ritorno.
Ciao
Gian Michele
--
Not in my name

 tu cosa hai in mente?
Niente di preciso. Mi sembrava di ricordare che ci fossero dei problemi
a considerare oggetti anche i tipi elementari.


 problemi a considerare oggetti anche i tipi elementari.
Beh, se trovi qualche riferimento piu' preciso te ne sarei grato. Magari
qualcuno c'illumina... :-)
Ciao
Gian Michele
--
"La scelta tra pace e guerra e' una scelta tra il bene e il male"

 int i.operator=(2.operator+(k));
Per gli operatori built-in questo non e' vero, la semantica e'
diversa. Ad esempio nella chiamata a funzione esiste un sequence point
tra la fine della valutazione dei parametri e l'inizio dell'esecuzione
della funzione, mentre non e' cosi' per un'espressione e le sue
sottoespressioni.
Un'altra differenza e' che ad esempio puoi chiamare una funzione
membro non const su oggetto temporaneo di un tipo definito
dall'utente, ma non puoi modificare un oggetto temporaneo di tipo
builtin. Questo ha la curiosa conseguenza che il seguente frammento di
codice:
vector<int> v;
v.push_back(2);
vector<int>::iterator i = --v.end();
E' valido se vector<int>::iterator e' implementato con una classe, ma
non lo e' se e' implementato con un puntatore a int.
Ciao,
Nicola

 builtin.
Per cercare di capire bene questo secondo problema ho scritto il
seguente programmino. Mi puoi dire se ho centrato il punto oppure no?
#include <iostream>
int Valore() { return 3; }
class Numero
{
    public:
        Numero(): num( 3 ) {}
        int operator -- () { return --num; }
    private:
        int num;
};
int main()
{
//    int n = --3;
//    int n = --Valore();
    int n = --Numero();
    std::cout << n << '\n';
    return 0;


 cosi' per un'espressione e le sue sottoespressioni.
Ok, tuttavia nel caso di operatori binari implementati globalmente e non
tramite funzione propria poiche' l'ordine di valutazione degli argomenti
di una funzione e' indefinito tanto quanto quello delle sottoespressioni
di un'espressione, mi sembra non ci siano differenze se non in alcuni
casi come p.e. con gli operatori logici e il comma-operator.
In fondo, per citare Meyers:
"Bjarne Stroustrup, the designer of C++, went to a lot of trouble to
ensure that user-defined types would mimic the built-in types as closely
as possible."
In sostanza il comportamento degli operatori ridefiniti mi sembra
*possa* essere reso compatibile (fatte le dovute eccezioni di cui sopra)
con quello degli operatori per i tipi predefiniti. Questo non vuol dire
che non si possano generare conseguenze come quella che hai mostrato nel
caso di vector<int>::iterator. In effetti mi piacerebbe sapere come mai
container.end() non restituisce un iterator const (cerco nelle FAQ?
^__^).


 container.end() non restituisce un iterator const (cerco nelle FAQ?
Secondo me la vera domanda e' piuttosto perche' non si impone che i
puntatori non siano iteratori validi per i vector, in modo da
garantire lo stesso comportamento degli iteratori degli altri
container.
A me e' capitato anche il problema opposto, ovvero non rendermi conto
che in un pezzo di codice davo per scontato che vector<>::iterator
fosse un puntatore; quando ho portato il mio codice su gcc 3.x ...
bum!
Ciao,
Nicola

 mio codice su gcc 3.x ...bum!
E quindi quando hai bisogno di un puntatore usi &*iterator?
Ciao
Gian Michele

   friend UBTest operator++(UBTest& rhs, int); //postfix
Ops, deve ritornare un const...

 E quindi quando hai bisogno di un puntatore usi &*iterator?
Idealmente si. Nel caso specifico pero' sarebbe stato piu' opportuno
generalizzare una soluzione esistente solo per puntatori a caratteri e
std::basic_string, solo che non si trattava di codice mio.
Ciao,
Nicola