Usted puede hacer esto:
template <typename T, unsigned int N>
std::ostream & operator<<(std::ostream & os, const T (&arr)[N])
{
// ..
return os;
}
esto sólo funciona para las matrices de tiempo de compilación, por supuesto. Tenga en cuenta que no tiene permiso para crear una instancia de esta plantilla cuando T
es un tipo integrado o un tipo en el espacio de nombres std
.
Probablemente sea mejor hacer esto en línea si es posible, ya que creará una instanciación separada para cada N
. (El pretty printer tiene un ejemplo de esto.)
Usted se dará cuenta, sin embargo, que la plantilla manta introduce una ambigüedad, porque os << "Hello"
ahora tiene dos sobrecargas posibles: la plantilla a juego const char (&)[6]
, y la (no molde) de sobrecarga para el decaimiento a puntero const char *
, que tienen secuencias de conversión idénticas. Podemos resolver esto mediante la desactivación de nuestra sobrecarga para arrays de 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;
}
De hecho, para ser aún más general también puede hacer las basic_ostream
parámetros parámetros de plantilla:
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;
}
En vista del hecho de que T
debe ser un tipo definido por el usuario, incluso podría reemplazar is_same<T, char>
con is_fundamental<T>
para obtener un poco más de comprobación (pero los usuarios aún no deben usar esto para matrices de tipos de biblioteca estándar).
gracias, pero yo don ¿No entiendo por qué causa una instanciación separada para cada N si no se implementa en línea? – Alcott
Bueno, es una plantilla, por lo que cada instancia de plantilla puede terminar como una función separada en tu archivo binario. Si está en línea, posiblemente puede evitar la llamada a la función por completo, aunque esto depende del compilador. –
lo tengo.Con este operador << que tiene 2 args de plantilla, ¿cómo podría especificar el segundo arg N? Aparentemente no puedo simplemente usar "cout << ar;" ¿puedo? – Alcott