我试图这样做:
template <typename T>
ostream &operator<<(ostream &os, T &arr)
{ /*...*/ }
但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;
}
我的实施是否合适?我收到了编译错误。
答案 0 :(得分:7)
你可以这样做:
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]
的模板,以及衰变的(非模板)重载 - to-pointer 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>
替换为is_fundamental<T>
以进行更多检查(但用户仍然不能使用这适用于标准库类型的数组。)
答案 1 :(得分:3)
您可以采用的另一种方法如下:
template<typename T>
ostream& operator<<(ostream &out, const std::pair<T, int>& array)
{
//...code
return out;
}
其中T
将获取指向数组的指针(即,它将是数组将衰减的指针类型),并且该对的int
部分将是数组。然后您可以像下面这样使用它:
int array[10];
//...some code that initializes array, etc.
cout << make_pair(array, 10);
使用此方法的一个优点是它也适用于动态数组(即您在堆上分配的数组等)。