在c++17/g++7中,终于有了期待已久的ostream_joiner。它可以使集合元素与中缀分隔符正确地输出到输出流中。
#include <algorithm>
#include <experimental/iterator>
#include <iostream>
#include <iterator>
#include <vector>
#include <string>
using string = std::string;
#if 1
struct pair {
string first;
string second;
};
#else
using pair = std::pair<string,string>;
#endif
std::ostream& operator<<(std::ostream& lhs, const pair &p) {
return lhs << p.first << "=" << p.second;
}
int main()
{
std::vector<pair> pairs = {{"foo", "bar"}, {"baz", "42"}};
std::copy(std::begin(pairs),
std::end(pairs),
std::experimental::make_ostream_joiner(std::cout, ", "));
}
尽管代码可以成功编译并输出结果...
foo=bar, baz=42
将代码片段中的 #if 1 改为 #if 0 会导致编译器报错,提示缺少正确的移位运算符:
main.cpp:29:70: required from here
/usr/local/include/c++/7.2.0/experimental/iterator:88:10: error: no match for
'operator<<' (operand types are
'std::experimental::fundamentals_v2::ostream_joiner<const char*, char,
std::char_traits<char> >::ostream_type {aka std::basic_ostream<char>}' and
'const std::pair<std::__cxx11::basic_string<char>,
std::__cxx11::basic_string<char> >')
*_M_out << __value;
有人知道为什么吗?
更新
Barry给出了正确的答案,但它并没有解决问题,而手动循环并不是重用现有STL代码的意义,因此问题得到扩展:
是否可能使流操作符在不污染std命名空间的情况下工作?
std
命名空间。 - Marek R