c++arraysiostream

Output a C array through ostream


I'm trying to output C array using iostream.

For array of ints, I wrote the code like this

template <size_t N>
ostream& operator<< (ostream& os, const int (&x)[N])
{
    for(int i=0; i<N; i++)
        os<<x[i]<<",";
    return os;
}
int main()
{
    int arr[]={1,2,3};
    cout<<arr<<endl;
    return 0;
}

And it works pretty fine.

Then, I'd generalize it to more types (like chars, floats etc), so I update the original version as follows

template <class T, size_t N>
ostream& operator<< (ostream& os, const T (&x)[N])
{
    for(int i=0; i<N; i++)
        os<<x[i]<<",";
    return os;
}

the main function didn't change, However, this time, when I compile it, error occured.

In function `std::ostream& operator<<(std::ostream&, const T (&)[N]) [with T = int, long unsigned int N = 3ul]':
a.cpp:15:   instantiated from here
a.cpp:9: error: ambiguous overload for `operator<<' in `(+os)->std::basic_ostream<_CharT, _Traits>::operator<< [with _CharT = char, _Traits = std::char_traits<char>]((*((+(((long unsigned int)i) * 4ul)) + ((const int*)x)))) << ","'
/usr/lib/gcc/x86_64-redhat-linux/3.4.5/../../../../include/c++/3.4.5/bits/ostream.tcc:121: note: candidates are: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(long int) [with _CharT = char, _Traits = std::char_traits<char>] <near match>
/usr/lib/gcc/x86_64-redhat-linux/3.4.5/../../../../include/c++/3.4.5/bits/ostream.tcc:155: note:                 std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(long unsigned int) [with _CharT = char, _Traits = std::char_traits<char>] <near match>
/usr/lib/gcc/x86_64-redhat-linux/3.4.5/../../../../include/c++/3.4.5/bits/ostream.tcc:98: note:                 std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(bool) [with _CharT = char, _Traits = std::char_traits<char>]

How can I fix this? thank you for any suggestions.


Solution

  • There already exists an overload for operator << (const char*) which is ambiguous with your template.

    You may restrict your template with SFINAE to exclude char:

    template <class T, size_t N,
         typename = typename std::enable_if<!std::is_same<char, T>::value>::type>
    ostream& operator<< (ostream& os, const T (&x)[N])