2012-02-23 4 views
7

Я хочу перегрузить operator<< для любых массивов, так что код cout << my_arr будет работать. Сначала я попытался перегрузить второй параметр operator<< на const T (&arr)[N], где T и N являются параметрами шаблона. Но тестирование кода показало побочный эффект: const char[] также соответствует спецификации типа, а новая перегрузка конфликтует с той, которая определена в классе потока. Пример кода:Оператор перегрузки << для массивов

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

Может ли такой оператор печати массива быть реализован?

+0

Я не думаю, что N будет хорошо переноситься во многих случаях. 'void f (int arr [], size_t N) {cout << arr; } ' –

+0

, если вам нужна внешняя библиотека, почему бы просто не использовать http://www.boost.org/doc/libs/1_48_0/doc/html/boost_lexical_cast.html – pyCthon

+1

@Captain:' arr' фактически имеет тип 'int * 'в этом случае, поэтому он не будет соответствовать этой перегрузке. –

ответ

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

Это приведет к отключению от перегрузки, когда T является char с помощью SFINAE.

Для C++ 03, Boost имеет enable_if и is_same. Альтернативно просто сворачивайте самостоятельно:

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

любое решение C++ 03? –

+1

@ Mr.Anubis: вместо этого используйте 'boost :: enable_if' и' boost :: is_same'. Если вы не хотите Boost, реализуйте их самостоятельно, эти два тривиально. –

+0

@GeorgFritzsche: Вы правы. Но так должно быть? Я предполагаю, что 'const T (&) []' также может связываться с неконстантным массивом, так что да, это прекрасно, как написано. Это более глубокие уровни 'const', которые нельзя добавить неявно. –

Смежные вопросы