【发布时间】:2012-02-21 13:59:50
【问题描述】:
今天我认为为 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 world\n";
error: ambiguous overload for 'operator<<' in 'std::cout << "hello world\012"'
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])
但我仍然对为什么编译器将数字类型视为候选者的问题感到困惑。
【问题讨论】:
标签: c++ arrays string templates operator-overloading