Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overload operator<< for arrays

I want to overload operator<< for arbitrary arrays, such that the code cout << my_arr would work. First I tried to overload the second parameter of operator<< on const T (&arr)[N], where T and N are template parameters. But testing the code revealed a side effect: const char[] also matches the type specification, and the new overload conflicts with the one defined in the stream class. Example code:

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

Can such an array printing operator still be implemented?

like image 845
Andrey Vihrov Avatar asked Feb 23 '12 21:02

Andrey Vihrov


People also ask

Can we overload << operator?

We can overload the '>>' and '<<' operators to take input in a linked list and print the element in the linked list in C++. It has the ability to provide the operators with a special meaning for a data type, this ability is known as Operator Overloading.

Can we overload << operator in C++?

You can redefine or overload the function of most built-in operators in C++. These operators can be overloaded globally or on a class-by-class basis. Overloaded operators are implemented as functions and can be member functions or global functions. An overloaded operator is called an operator function.

Can you overload array?

In the C++ programming language, it is possible to overload the index operator of the elements of the array [ ]. This operator is considered unary, that is, it requires one parameter – the array index. So, it is advisable to overload the [ ] operator in classes where arrays are used.


1 Answers

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

This will disable your overload when T is char using SFINAE.

For C++03, Boost has enable_if and is_same. Alternatively just roll your own:

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; 
};
like image 76
Georg Fritzsche Avatar answered Sep 21 '22 03:09

Georg Fritzsche