Newsgroup: it.comp.lang.c++
Titolo: inzializzare classe come array

Salve a tutti,
una domanda su un'inizializzazione che potrebbe essere assurda.
Ho una mia classe MioVettore; è possibile inizializzarne un oggetto 
nella dichiarazione come si fa per un array?
Cioè, così come posso fare
int vett[3]={2,1,5,2};
c'è un modo per definire un costruttore in modo che sia lecita l'istruzione
MioVettore primiprimi={2,3,5,7};
o al limite
MioVettore primiprimi({2,3,5,7});
?
(dove ovviamente la lunghezza non sia stabilita a priori).
Ho cercato ovunque ma non trovo niente di simile; mi pare che anche con 
la classe vector non si possa.
Grazie
Marco

 la classe vector non si possa.
Che io sappia non si puň.
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
The EMG Music page:         
http://www.emagsoftware.it/emgmusic

 la classe vector non si possa.
La cosa più simile che puoi fare è
  int values[] = {1,3,5,6,7,2,3,4};
  std::vector<int> v( values, values+sizeof(values)/sizeof(int) );
M

 
Ah, ok. Avevo visto questo modo ma speravo in qualcosa di piů "pulito".
Mi sa che non si puň proprio eh..
Grazie mille.
Ciao
marco

 Marco
Un modo pulito non esiste.
Ci sono delle macro con argomenti variabili in BOOST che 
potrebbero fare al caso tuo per generare liste.
Cmq tieni presente che si tratterebbe di fare in realtà template 
di classi, che quindi non sarebbero tipi uguali ma distingi
Per inizializzare oggetti con le graffe tieni anche presenti 
molte limitazioni (cerca sotto AGGREGATES), alcune non le 
ricordo, ti cito quelle che ricordo
L'oggetto non deve fornire nessun costruttore con argomenti, 
forse è ammesso un solo default constructor (o forse è vietato, 
abbi pazienza non ricordo)
Non ci devono essere membri dati privati o protetti né costanti 
né static (quasi come una struct in effetti)
In caso si tratti di oggetto composto, ogni sotto membro sino 
all'ultimo livello deve soddisfare i medesimi requisiti
Controlla gli altri requisiti ed anche la nidificazione delle 
graffe.
Ah, i membri e sotto oggetti devono essere inizializzati nel 
medesimo ordine in cui sono dichiarati, per cui un oggetto fatto 
così
class Silly
{
long L;
int Arr [3];
char * name;
}
si inizializza così
Silly A = {2L, {4, 5, 6}, "scemo"};
le graffe sono opzionali in caso di liste complete (ma sempre 
molto più chiare), mentre in caso di inizializzazioni 
INCOMPLETE, possibili (l'overflow è invece errore), risultano 
essenziali a dire come distrubuire i pochi dati presenti.
cmq studiati un po' le macro della libreria BOOST, che possono 
fare cose davvero insolite
sui template dicevo che puoi parametrizzare (non in modo 
dinamico cmq ma noto a compile time) le dimensioni dell'array, 
ma crei istanze di classi distinte, ciascuna che richiede una 
lista il cui numero di inizializzatori sia coerente con i membri 
effettivi e dimensioni specifiche dell'array.
{}
 > MioVettore primiprimi={2,3,5,7};
ciao
Soviet-Mario


wrote:

Non sono un esperto di template, pero' questo mi
sembra un po' piu' simile a quello che cerca l'OP:
#include <iostream>
template<class V>
class MyVect
{
    private:
        V *data_;
        int n_;
    public:
        MyVect(V *data, int n)
            : data_(new V[n]), n_(n)
        {
            for (int i=0; i<n_; i++)
                data_[i] = data[i];
        }
        template<int n>
        MyVect(V (&data)[n])
            : data_(new V[n]), n_(n)
        {
            for (int i=0; i<n_; i++)
                data_[i] = data[i];
        }
        ~MyVect()
        {
            delete[] data_;
        }
        int size() const
        {
            return n_;
        }
 
        V& operator[](int index)
        {
            return data_[index];
        }
 
        const V& operator[](int index) const
        {
            return data_[index];
        }
    private:
        // Taboo
        MyVect(const MyVect&);
        MyVect& operator=(const MyVect&);
};
int main()
{
    double x[] = {1,2,3,4};
    MyVect<double> v(x);
    for (int i=0; i<v.size(); i++)
        std::cout << v[i] << "\n";
}
E' anche possibile permettere la creazione di un MyVect<double>
passando ad esempio un array di interi (o di qualunque cosa
che possa essere convertita implicitamente a double) modificando
il costruttore template come:
        template<int n, class X>
        MyVect(X (&data)[n])
            : data_(new V[n]), n_(n)
        {
            for (int i=0; i<n_; i++)
                data_[i] = data[i];
        }
Questo codice che dichiara parametri di tipo reference
ad array pero' compila con bcc55, g++ 3.3.3, vc++ 2003
ma non compila ad esempio con VC++ 6 (compilatore credo
ancora molto diffuso anche se estremamente carente in
queste areee del C++).
Forse prima di usare cose del genere sarebbe meglio oltre
alla valutazione di chi riuscira' ad usarlo verificare anche
il rischio bloating ed eventualmente portare tutto il codice
effettivo del costruttore se fosse di una qualche corposita'
in una funzione esterna non inline (anche se "a naso" un
minimo relativo alla gestione exception sono convinto che
rimarrebbe comunque inutilmente ripetuto per ogni invocazione
o nel caso piu' roseo per ogni dimensione di array).
Qualcuno direbbe che e' una mera questione di QOI, ma un
eseguibile da 20Mb non diventa di 2Mb recitando la formula
magica "e' solo un problema di QOI".
Spero anche che si tratti effettivamente di codice C++
legale; sono ragionevolmente fiducioso ma non ci scommetterei
il primogenito. Il fatto che qualcosa compili purtroppo non
e' mai stato sufficiente come dimostrazione (come il fatto
che qualcosa NON compili non e' una dimostrazione che il
codice non e' C++; c'e' chi si e' guadagnato da vivere
scrivendo librerie intere in C++ legale che pero' non
compilavano su nessun compilatore disponibile ai tempi).
HTH
Andrea