这是@nm 的解决方案,没有粗鲁的全球贪婪operator<<
。
template<class Os>
struct chain_stream {
Os& stream;
template<class Rhs,
std::enable_if_t<std::is_same_v<Os&, decltype(std::declval<Os&>() << std::declval<Rhs>())>, bool> =true
>
friend chain_stream<Os> const& operator<<( chain_stream<Os> const& os, Rhs&& rhs ) {
os.stream << std::forward<Rhs>(rhs);
return os;
}
// iomanipulator:
friend chain_stream<Os> const& operator<<( chain_stream<Os> const& os, Os&(*rhs)(Os&) ) {
os.stream << rhs;
return os;
}
template<class Rhs,
std::enable_if_t<
std::is_same_v< std::result_of_t< Rhs&&(chain_stream const&) >, void >
|| std::is_same_v< std::result_of_t< Rhs&&(chain_stream const&) >, Os& >,
bool> =true
>
friend chain_stream<Os> const& operator<<( chain_stream<Os> const& os, Rhs&& rhs ) {
std::forward<Rhs>(rhs)( os );
return os;
}
};
现在我们可以这样做:
(chain_stream{std::cout} << ... << [&](auto& x){x << args << '\n';});
它有效。