2012-02-23 17 views
7

Chcę przeciążać operator<< dla dowolnych tablic, tak aby zadziałał kod cout << my_arr. Najpierw próbowałem przeciążyć drugi parametr operator<< na const T (&arr)[N], gdzie T i N są parametrami szablonu. Ale testowanie kodu ujawniło efekt uboczny: const char[] również pasuje do specyfikacji typu, a nowe przeciążenie powoduje konflikt z definicją zdefiniowaną w klasie strumienia. Przykład Kod:Przeciążenie operatora << dla tablic

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

można taki operator drukowania matryca nadal realizowane?

+0

Nie sądzę, że w dobrych przypadkach N będzie się dobrze przenosić. 'void f (int arr [], size_t N) {cout << arr; } ' –

+0

jeśli chcesz zewnętrzną bibliotekę, po prostu użyj http://www.boost.org/doc/libs/1_48_0/doc/html/boost_lexical_cast.html – pyCthon

+1

@Captain:' arr' faktycznie ma typ 'int * 'w takim przypadku, więc nie pasowałoby do tego przeciążenia. –

Odpowiedz

5

Sure:

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

To spowoduje wyłączenie przy przeciążeniu T jest char użyciu SFINAE.

Dla C++ 03, Boost ma enable_if i is_same. Ewentualnie po prostu zrób własne:

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

dowolne rozwiązanie C++ 03? –

+1

@ Mr.Anubis: Zamiast tego użyj 'boost :: enable_if' i' boost :: is_same'. Jeśli nie chcesz Boost, zaimplementuj je sam, te dwa są trywialne. –

+0

@GeorgFritzsche: Masz rację. Ale czy to powinno być? Przypuszczam, że 'const T (&) []' może również wiązać się z tablicą non-const, więc tak, to jest w porządku, jak napisano. To jest głębszy poziom 'const', którego nie można dodać niejawnie. –

Powiązane problemy