Domanda

Sto usando un inizializzatore aggregato di creare un blocco di dati statici per un test di unità.

desidero utilizzare la dimensione della matrice come il numero atteso di elementi, ma questo può non riuscire se sono forniti troppo pochi initializers:

my_struct_type expected[14] =
{
    { 1.234, 0, 'c' },
    { 3.141, 1, 'z' },
    { 2.718, 0, 'a' }
};

Questo dà alcun errore del compilatore in Visual Studio 2008.

Mi piacerebbe essere in grado di usarlo come tale:

const unsigned expected_size = sizeof(expected) / sizeof(my_struct_type);

BOOST_CHECK_EQUAL(points.size(), expected_size);

for( int i = 0; i < expected_size; i++ )
{
    BOOST_CHECK_EQUAL(points[i].value, expected[i].value);
    BOOST_CHECK_EQUAL(points[i].count, expected[i].count);
    BOOST_CHECK_EQUAL(points[i].sym,   expected[i].sym);
}

, ma perché non ho una garanzia in fase di compilazione di 14 punti, questo scappa il fine della matrice fine dei valori previsti e nei valori di default-inizializzato.

Posso in qualche modo far rispettare il numero di inizializzatori di array aggregati a tempo di compilazione?

È stato utile?

Soluzione

In primo luogo: Ci potrebbe essere un avvertimento per questo. Hai provato la compilazione al livello di allarme più alto?

Quindi: Se si scambia il cui valore viene calcolato, e che è letterale, si potrebbe sollevare un errore di compilazione:

my_struct_type my_array[] = // <== note the empty []
{
    { 1.234, 0, 'c' },
    { 3.141, 1, 'z' },
    { 2.718, 0, 'a' }
};

BOOST_STATIC_ASSERT( sizeof(my_array)/sizeof(my_array[0]) == 14 );

Altri suggerimenti

In realtà non sarà eseguito al largo della fine della matrice, perché il compilatore di default-inizializzare tutti gli elementi della matrice che non è stato inizializzato da soli.

Se si sta cercando di fare in modo che si dispone di un numero specifico di initializers configurati, io non sono sicuro di come fare questo.

Se si desidera solo per assicurarsi che la matrice è il numero di elementi che si hanno:

my_struct_type expected[] =
{
    { 1.234, 0, 'c' },
    { 3.141, 1, 'z' },
    { 2.718, 0, 'a' }
};

farà il trucco. Poi basta usare sizeof(expected) / sizeof(expected[0]) per ottenere il numero totale di elementi di matrice.

Solo per il gusto di una risposta non-Boost ...

È possibile aggiungere un requisito di inizializzazione modificando my_struct_type.

template< typename T >
struct must_be_initialized {
    T value;

    must_be_initialized( T const &v ) : value( v ) {}
     // no default constructor!

    operator T& () { return value; }
    operator T const& () const { return value; }
};

struct my_struct_type {
    must_be_initialized< double > f;
    int i;
    char c;
};

my_struct_type expected[14] =
{
    { 1.234, 0, 'c' },
    { 3.141, 1, 'z' },
    { 2.718, 0, 'a' }
     // error: no default constructor exists
};

my_struct_type è ancora un aggregato, ma non è POD.

ISO / IEC 14882 (prima edizione 1998/09/01) in p. 8.5.1.7 stati i seguenti:

  

Se ci sono meno inizializzatori nel   lista che ci sono membri in   aggregato, allora ogni membro non   esplicitamente inizializzato sarà   default-inizializzato (8.5). [Esempio:   struct S {int a; char * b; int c; }; S   ss = {1, "asdf"}; inizializza ss.a   con 1, ss.b con "asdf", e ss.c   con il valore di espressione del   forma int (), che è, 0.]

Semplicemente, la risposta alla tua domanda è no.

Secondo il MSDN , se un minor numero di inizializzatori sono specificato, gli elementi restanti vengono inizializzati con 0, quindi il codice dovrebbe funzionare comunque.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top