重载运算符<<用于数组
overloading operator<< for arrays
今天我认为为C风格数组重载operator<<
是个好主意:
template<typename T, size_t N>
std::ostream& operator<<(std::ostream& os, T(&a)[N])
{
os << '{' << a[0];
for (size_t i = 1; i < N; ++i)
{
os << ',' << ' ' << a[i];
}
os << '}';
return os;
}
int main()
{
int numbers[] = {2, 3, 5, 7, 11, 13, 17, 19};
std::cout << numbers << 'n';
}
事实上,这很好地打印了{2, 3, 5, 7, 11, 13, 17, 19}
。然而,通过提供这种重载,我无法再打印字符串文字:
std::cout << "hello worldn";
error: ambiguous overload for 'operator<<' in 'std::cout << "hello world 12"'
note: candidates are:
note: std::basic_ostream<_CharT, _Traits>::__ostream_type&
std::basic_ostream<_CharT, _Traits>::operator<<(long int) [with _CharT = char, _
Traits = std::char_traits<char>, std::basic_ostream<_CharT, _Traits>::__ostream_
type = std::basic_ostream<char>] <near match>
note: no known conversion for argument 1 from 'const char [13]' to 'long int'
这实在令人费解。为什么编译器在没有从const char[13]
到long int
的转换的情况下甚至考虑long int
重载?
long unsigned int
、short int
、short unsigned int
、int
、unsigned int
、long long int
和long long unsigned int
出现此错误消息的变体。
(其他候选者是const void*
、const char*
和const _CharT*
,以及我自己的模板。)
我通过只提供非字符类型的模板解决了这个问题:
template<typename T, size_t N>
typename std::enable_if<
!std::is_same<typename std::remove_cv<T>::type, char>::value,
std::ostream&>::type operator<<(std::ostream& os, T(&a)[N])
但我仍然对编译器为什么将数字类型视为候选类型的问题感到困惑。
重载解析的第一阶段是确定可行的函数,这些函数可以接受所提供的参数数量(完全忽略类型)。(参见13.3.2[超过匹配可行])。
然后考虑任何需要的转换,以确定哪一个是唯一的最佳可行函数。
在这种情况下,没有这样独特的最佳(有两个同样优秀的候选人)。
错误消息可以告诉你这两种不明确的情况。但我认为他们试图通过展示为什么所有其他可行的功能都失败来提供帮助。有时,当您无法弄清楚为什么没有考虑要调用的函数时,这很有用。
但我同意,大多数情况下,这只是很多噪声,尤其是对于像operator <<
或operator >>
(甚至operator []
)这样有很多过载的函数。
编译器拒绝程序是正确的。我认为关键是您的过载和ostream::operator<<( char const * )
都出现在错误消息中。积分可能是转移注意力……你可以将reinterpret_cast
作为指向long int
(§5.2.10/4)的指针(或字符串文字),但这肯定不是标准的转换。也许编译器只是想通过给你更多的重载来提供帮助。
考虑到您的过载和ostream
成员,过载解决失败只是因为在它们之间没有优先级规则(§13.3.1.2)。因此,由于char const *
成员过载是唯一可能发生冲突的过载,因此您的修复似乎是合适的。
- Mongodb c++驱动程序:如何查询元素的数组
- 将数组的地址分配给变量并删除
- 从C++本机插件更新Vector3数组
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 数组索引的值没有增加
- 将对象数组的引用传递给函数
- 为char数组调整zlib-zpipe
- 2D数组来自文本输入,中间有空格
- std::向量与传递值的动态数组
- 在c++中用vector填充一个简单的动态数组
- 使用strcpy将char数组的元素复制到另一个数组
- 使用指针从C++中的数组中获取最大值
- C++使用整数的压缩数组初始化对象
- 告诉一个 const char 数组,除了编译时 C 样式的字符串外,它不以 '