通过ostream输出C数组

问题描述 投票:0回答:3

我正在尝试使用 iostream 输出 C 数组。

对于整数数组,我写了这样的代码

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;
}

而且效果非常好。

然后,我将其推广到更多类型(如字符、浮点数等),因此我按如下方式更新原始版本

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;
}

main函数没变,但是这次编译的时候,出现了错误。

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>]

我该如何解决这个问题?谢谢您的任何建议。

c++ arrays iostream
3个回答
6
投票

已经存在

operator << (const char*)
的重载,这与您的模板不明确。

您可以使用 SFINAE 限制您的模板以排除

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])

1
投票

编译器实际上是在抱怨

","
。如果你删除它,你会发现它工作正常。

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

字符串文字的类型是

N
const char 的数组,但它会衰减为
const char*
,从而在
os << x[i] << ","
调用中产生歧义。


0
投票

这实际上是一个很好的例子:在调用时,数组还没有衰减,因此数组长度被保留并且可以作为模板参数传递。非常聪明!

这可以在现代 C++ 中使用 ostream_iterator 和复制算法来实现:

template<class T, size_t N
  typename = typename std::enable_if<!std::is_same<char, T>::value>::type>
std::ostream& operator<<(std::ostream& os, const T (&arr)[N]) {
   std::copy_n(arr, N, std::ostream_iterator<T>(os, ", "));
   return os;
}

它具有所需的输出

1, 2, 3, 

(我使用默认的 C++17 使用 gcc 11.4.0 对此进行了测试。)

© www.soinside.com 2019 - 2024. All rights reserved.