我想<<
为任何人写一个通用的range
,我最终得到了这个:
std::ostream& operator << (std::ostream& out, std::ranges::range auto&& range) {
using namespace std::ranges;
if (empty(range)) {
return out << "[]";
}
auto current = begin(range);
out << '[' << *current;
while(++current != end(range)) {
out << ',' << *current;
}
return out << ']';
}
像这样测试:
int main() {
std::vector<int> ints = {1, 2, 3, 4};
std::cout << ints << '\n';
}
它完美地工作并输出:
[1,2,3,4]
但是,当测试时:
int main() {
std::vector<int> empty = {};
std::cout << empty << '\n';
}
它出乎意料地输出:
[[,], ]
用调试器运行这段代码,我得出一个结论,空范围的问题是我们运行return out << "[]";
. 一些 C++ 魔法决定了我刚刚写的,
std::ostream& operator << (std::ostream& out, std::ranges::range auto&& range);
是更好的匹配,然后提供<ostream>
,
template< class Traits >
basic_ostream<char,Traits>& operator<<( basic_ostream<char,Traits>& os,
const char* s );
因此,它不像我们通常看到的那样仅发送"[]"
到输出流,而是递归回自身,但"[]"
作为range
参数。
那是更好的匹配的原因是什么?[
与]
单独发送相比,我可以以更优雅的方式解决此问题吗?
编辑:这似乎很可能是 GCC 10.1.0 中的一个错误,因为较新的版本拒绝该代码。