2012-02-23 35 views
7

Quiero sobrecargar operator<< para matrices arbitrarias, de modo que el código cout << my_arr funcionaría. Primero intenté sobrecargar el segundo parámetro de operator<< en const T (&arr)[N], donde T y N son parámetros de plantilla. Pero probar el código reveló un efecto secundario: const char[] también coincide con la especificación de tipo, y la nueva sobrecarga entra en conflicto con la definida en la clase de flujo. Código de ejemplo:Operador de sobrecarga << para matrices

#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 */ 
} 

¿Se puede implementar dicho operador de impresión de matriz?

+0

No creo que N se transfiera bien en muchos casos. 'void f (int arr [], size_t N) {cout << arr; } ' –

+0

si quiere una biblioteca externa, ¿por qué no usar simplemente http://www.boost.org/doc/libs/1_48_0/doc/html/boost_lexical_cast.html – pyCthon

+1

@Captain:' arr' en realidad tiene el tipo 'int * 'en ese caso, entonces no coincidiría con esa sobrecarga. –

Respuesta

5

Claro:

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]) 
{ 
    // ... 
} 

Esto desactivará su sobrecarga cuando T es char usando SFINAE.

Para C++ 03, Boost tiene enable_if y is_same. Alternativamente, solo haga su propia:

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

¿alguna solución de C++ 03? –

+1

@ Mr.Anubis: Use 'boost :: enable_if' y' boost :: is_same' en su lugar. Si no quiere Boost, impleméntelo usted mismo, estos dos son triviales. –

+0

@GeorgFritzsche: Tienes razón. Pero debería ser? Supongo que 'const T (&) []' también puede unirse a una matriz no const, así que sí, está bien como está escrito. Son niveles más profundos de 'const' que no pueden agregarse implícitamente. –

Cuestiones relacionadas