2012-02-23 19 views
7

Desidero sovraccaricare lo operator<< per gli array arbitrari, in modo che il codice cout << my_arr funzionasse. Innanzitutto ho provato a sovraccaricare il secondo parametro di operator<< su const T (&arr)[N], dove T e N sono parametri del modello. Ma testare il codice ha rivelato un effetto collaterale: const char[] corrisponde anche alla specifica del tipo e il nuovo overload è in conflitto con quello definito nella classe stream. Esempio codice:Operatore di sovraccarico << per gli array

#include <cstddef> 
#include <iostream> 

template<typename T, std::size_t N> 
std::ostream& operator<<(std::ostream& os, const T (&arr)[N]) 
{ 
    /* do stuff */ 
    return os; 
} 

int main() 
{ 
    std::cout << "noooo\n"; /* Fails: ambiguous overload */ 
} 

È possibile implementare un operatore di stampa di array di questo tipo?

+0

Non credo che N si trasferirà bene in molti casi. 'void f (int arr [], size_t N) {cout << arr; } –

+0

se si desidera una libreria esterna, perché non utilizzare semplicemente http://www.boost.org/doc/libs/1_48_0/doc/html/boost_lexical_cast.html – pyCthon

+1

@Captain: "arr' ha effettivamente il tipo" int * 'in tal caso, quindi non corrisponderebbe a tale sovraccarico. –

risposta

5

Certo:

template<typename T, std::size_t N> 
typename std::enable_if<!std::is_same<T, char>::value, std::ostream&>::type 
operator<<(std::ostream& os, const T (&arr)[N]) 
{ 
    // ... 
} 

Questo disabiliterà il tuo sovraccarico quando T è char utilizzando SFINAE.

Per C++ 03, Boost ha enable_if e is_same. In alternativa, è sufficiente rollare il proprio:

template<class T, class U> struct is_same { 
    enum { value = false }; 
}; 
template<class T> struct is_same<T, T> { 
    enum { value = true }; 
}; 

template<bool, class T> struct enable_if {}; 
template<class T> struct enable_if<true, T> { 
    typedef T type; 
}; 
+0

una qualsiasi soluzione C++ 03? –

+1

@ Mr.Anubis: usa invece 'boost :: enable_if' e' boost :: is_same'. Se non vuoi Boost, implementalo tu stesso, questi due sono banali. –

+0

@GeorgFritzsche: hai ragione. Ma dovrebbe essere? Immagino che 'const T (&) []' possa legarsi anche a un array non-const, quindi sì, va bene come scritto. Sono i livelli più profondi di 'const' che non possono essere aggiunti implicitamente. –

Problemi correlati