你可以这样做:
template <typename T, unsigned int N>
std::ostream & operator<<(std::ostream & os, const T (&arr)[N])
{
// ..
return os;
}
当然,这只适用于编译时数组。请注意,以下情况不允许您实例化此模板:T
是内置类型还是中的类型std
命名空间!
如果可能的话,最好使其内联,因为您将为每个N
. (The 漂亮的打印机 https://stackoverflow.com/questions/4850473/pretty-print-c-stl-containers有一个这样的例子。)
不过,您会注意到,总括模板引入了歧义,因为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;
}
事实上,为了更通用,你还可以使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>
with is_fundamental<T>
进行更多检查(但用户仍然不能将其用于标准库类型的数组)。