È possibile utilizzare C++ 0xauto
parola chiave insieme specializzazione modello, ad esempio una funzione denominata boost::make_array()
(simile a make_pair()
). Per il caso di cui N
è 1 o 2 argomenti poi possiamo scrivere variante A come
namespace boost
{
/*! Construct Array from @p a. */
template <typename T>
boost::array<T,1> make_array(const T & a)
{
return boost::array<T,2> ({{ a }});
}
/*! Construct Array from @p a, @p b. */
template <typename T>
boost::array<T,2> make_array(const T & a, const T & b)
{
return boost::array<T,2> ({{ a, b }});
}
}
e variante B come
namespace boost {
/*! Construct Array from @p a. */
template <typename T>
boost::array<T,1> make_array(const T & a)
{
boost::array<T,1> x;
x[0] = a;
return x;
}
/*! Construct Array from @p a, @p b. */
template <typename T>
boost::array<T,2> make_array(const T & a, const T & b)
{
boost::array<T,2> x;
x[0] = a;
x[1] = b;
return x;
}
}
GCC-4.6 con -std=gnu++0x
e -O3
genera il identico stesso codice binario per
auto x = boost::make_array(1,2);
utilizzando sia A e B come per
boost::array<int, 2> x = {{1,2}};
Per definiti dall'utente tipi (UDT), però, risultati variante B nelle un'altra copia costruttore, che di solito rallentare le cose, e dovrebbe quindi essere evitato.
noti che boost::make_array
errori quando si chiama con letterali esplicita matrice char come nel seguente caso
auto x = boost::make_array("a","b");
Credo che questa è una buona cosa in quanto const char*
letterali può essere ingannevole nel loro uso.
variadic modelli, disponibili in GCC dal 4,5, può essere ulteriormente utilizzato ridurre tutto il codice boilerplate template specializzazione per ogni N
in una definizione singolo modello di boost::make_array()
definiti come
/*! Construct Array from @p a, @p b. */
template <typename T, typename ... R>
boost::array<T,1+sizeof...(R)> make_array(T a, const R & ... b)
{
return boost::array<T,1+sizeof...(R)>({{ a, b... }});
}
Funziona praticamente come ci aspettiamo. Il primo argomento determina l'argomento modello boost::array
T
e tutti gli altri argomenti vengono convertiti in T
. Per alcuni casi questo potrebbe non essere desiderabile, ma non sono sicuro di come sia possibile specificare l'uso di modelli variadici.
Forse boost::make_array()
dovrebbe entrare nelle librerie Boost?
Le classi non sono costruibili perché tutto è 'private'. –
(parole chiave di accesso rimandate per semplicità pedagogica) –
Non sarebbe più semplice usare 'struct' al posto di' class' per semplicità pedagogica? Trovo il codice che compila più facilmente da cui imparare ;-) –