你可以这样做:
template <typename T, unsigned int N>
std::ostream & operator<<(std::ostream & os, const T (&arr)[N])
{
// ..
return os;
}
当然,这只适用于编译时数组。请注意,当T 是内置类型或std 命名空间中的类型时,不允许实例化此模板!
如果可能,最好将其设为内联,因为您将为每个 N 单独实例化。 (pretty printer 有一个例子。)
不过,您会注意到,总括模板引入了歧义,因为 os << "Hello" 现在有两个可能的重载:匹配 const char (&)[6] 的模板,以及衰减指针 @ 的(非模板)重载987654328@,两者具有相同的转换序列。我们可以通过禁用 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;
}
其实更通用的你也可以将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;
}
鉴于T 必须是用户定义的类型,您甚至可以将is_same<T, char> 替换为is_fundamental<T> 以进行更多检查(但用户仍然不能将其用于标准库的数组类型)。