怎么重载operator << for C++中的数组?

Alc*_*ott 6 c++ operator-overloading

我试着这样做:

template <typename T>
ostream &operator<<(ostream &os, T &arr)
{ /*...*/ }
Run Code Online (Sandbox Code Playgroud)

但是可以T代表一个阵列吗?<<为阵列重载运算符是否正确?


编辑:

根据Kerrek SB的建议,这是我的实现<<:

template <typename T, unsigned int N>
ostream &operator<<(ostream &os, const T (&arr)[N])
{
    int i;
    for(i = 0; i < N; i++)
        os << arr[i] << " ";
    os << endl;
    return os;
}
Run Code Online (Sandbox Code Playgroud)

我的实施是对的吗?我收到了编译错误.

Ker*_* SB 8

你可以这样做:

template <typename T, unsigned int N>
std::ostream & operator<<(std::ostream & os, const T (&arr)[N])
{
  // ..
  return os;
}
Run Code Online (Sandbox Code Playgroud)

当然,这仅适用于编译时数组.请注意,如果T是内置类型或std命名空间中的类型,则不允许您实例化此模板!

如果可能的话,可能最好使这个内联,因为你将为每个实例单独实例化N.(漂亮的打印机有一个例子.)

但是,您会注意到毯式模板引入了歧义,因为os << "Hello"现在有两个可能的重载:模板匹配const char (&)[6]和衰减到指针的(非模板)重载const char *,它们都具有相同的转换序列.我们可以通过禁用char数组的重载来解决这个问题:

#include <ostream>
#include <type_traits>

template <typename T, unsigned int N>
typename std::enable_if<!std::is_same<T, char>::value, std::ostream &>::type
operator<<(std::ostream & os, const T (&arr)[N])
{
  // ..
  return os;
}
Run Code Online (Sandbox Code Playgroud)

实际上,为了更加通用,您还可以制作basic_ostream参数模板参数:

template <typename T, unsigned int N, typename CTy, typename CTr>
typename std::enable_if<!std::is_same<T, char>::value,
                        std::basic_ostream<CTy, CTr> &>::type
operator<<(std::basic_ostream<CTy, CTr> & os, const T (&arr)[N])
{
  // ..
  return os;
}
Run Code Online (Sandbox Code Playgroud)

鉴于这样的事实T必须是用户定义类型,你甚至可以更换is_same<T, char>is_fundamental<T>获得更多的检查(但用户仍然不能使用这个标准库类型的数组).