更新时间:2023-02-14 19:40:12
您可以这样做:
template <typename T, unsigned int N>
std::ostream & operator<<(std::ostream & os, const T (&arr)[N])
{
// ..
return os;
}
这当然只适用于编译时数组。请注意, T
是内置类型或 std
中的类型时,不允许实例化此模板,命名空间!
This works only for compile-time arrays, of course. Note that you are not allowed to instantiate this template when T
is a built-in type or a type in the std
namespace!
如果可能的话,***尽可能使这个内联,因为你会为每个 N
。 (漂亮的打印机有此示例。)
Probably best to make this inline if possible, since you'll cause a separate instantiation for every N
. (The pretty printer has an example of this.)
你会注意到,毯子模板引入了歧义,因为 os<< Hello
现在有两个可能的重载:模板匹配 const char(&)[6]
对于衰减到指针 const char *
,它们都具有相同的转换序列。我们可以通过禁用字符数组的重载来解决这个问题:
You will notice, though, that the blanket template introduces an ambiguity, because os << "Hello"
now has two possible overloads: the template matching const char (&)[6]
, and the (non-template) overload for the decay-to-pointer const char *
, which both have identical conversion sequences. We can resolve this by disabling our overload for char arrays:
#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
参数模板参数:
In fact, to be even more general you can also make the basic_ostream
parameters template parameters:
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_fundamental< T> $ c替换
is_same
In view of the fact that T
must be a user-defined type, you could even replace is_same<T, char>
with is_fundamental<T>
to get a bit more checking (but users still must not use this for arrays of standard library types).