Si potrebbe fare questo:
template <typename T, unsigned int N>
std::ostream & operator<<(std::ostream & os, const T (&arr)[N])
{
// ..
return os;
}
Questo funziona solo per gli array in fase di compilazione, naturalmente. Si noti che non è consentito creare un'istanza di questo modello quando T
è un tipo incorporato o un tipo nello spazio dei nomi std
!
Probabilmente è meglio rendere questo in linea se possibile, poiché si creerà un'istanza separata per ogni N
. (Il pretty printer ha un esempio di questo.)
Noterete, però, che il modello di coperta presenta un'ambiguità, perché os << "Hello"
ha ora due possibili sovraccarichi: il modello di corrispondenza const char (&)[6]
, e la (non-modello) sovraccarico per il decay-to-pointer const char *
, che hanno entrambe sequenze di conversione identiche. Siamo in grado di risolvere questo disabilitando la nostra sovraccarico per gli array char:
#include <ostream>
#include <type_traits>
template <typename T, unsigned int N>
typename std::enable_if<!std::is_same<T, char>::value, std::ostream &>::type
operator<<(std::ostream & os, const T (&arr)[N])
{
// ..
return os;
}
In realtà, per essere ancora più generale si può anche fare i basic_ostream
parametri parametri di modello:
template <typename T, unsigned int N, typename CTy, typename CTr>
typename std::enable_if<!std::is_same<T, char>::value,
std::basic_ostream<CTy, CTr> &>::type
operator<<(std::basic_ostream<CTy, CTr> & os, const T (&arr)[N])
{
// ..
return os;
}
In considerazione del fatto che T
deve essere un tipo definito dall'utente, è anche possibile sostituire is_same<T, char>
con is_fundamental<T>
per ottenere un controllo un po 'più (ma gli utenti non devono ancora utilizzare questo per gli array di tipi di libreria standard).
grazie, ma io don capisco perché causa un'istanza separata per ogni N se non implementata in linea? – Alcott
Bene, è un modello, quindi ogni istanza di modello può finire come una funzione separata nel tuo file binario. Se si è in linea, è possibile evitare del tutto la chiamata alla funzione, anche se in definitiva ciò dipende dal compilatore. –
capito.Con questo operatore << con 2 template args, come potrei specificare il secondo arg N? Apparentemente non posso semplicemente usare "cout << ar;", posso? – Alcott