c++ - Overload operator>> for std::pair<int, int> -
i trying use boost::lexical_cast
on std::pair<int, int>
.
#include <iostream> #include <utility> #include <boost/lexical_cast.hpp> namespace { // when my_pair user defined type, program compiles // , runs without problems. // when declaring my_pair alias of std::pair<int, int>, // fails compile /* struct my_pair { int first; int second; }; */ using my_pair = std::pair<int, int>; std::istream& operator>>(std::istream& stream, my_pair& pair) { stream >> pair.first; stream >> std::skipws; stream >> pair.second; return stream; } } int main() { my::my_pair p = boost::lexical_cast<my::my_pair>("10 10"); std::cout << p.first << " " << p.second << std::endl; return 0; }
if understand right, in order make adl work, operator>> has in same namespace my_pair, std.
doing so, result in undefined behavior, because adding functions namespace std.
i avoid inheritance, in struct my_pair : std::pair<int, int>
.
what solution problem?
i using clang++-3.6 on os x.
instead of adl-hooking on value stream, overload on stream (tagging in way):
int main() { std::map<int, std::string> standback { { 42, "i'm gonna try" }, { 1729, "science" } }; streaming::tag_ostream out = std::cout; (auto& entry : standback) out << entry << "\n"; }
this way, can adl-hook on namespace under control. can make tagging more generic (think auto out = streaming::tag(std::cout)
).
now, simple implementation of like
namespace streaming { template <typename t> struct tag : std::reference_wrapper<t> { using std::reference_wrapper<t>::reference_wrapper; }; using tag_ostream = tag<std::ostream>; template <typename t1, typename t2> static inline tag_ostream operator<<(tag_ostream os, std::pair<t1, t2> const& p) { os.get() << "std::pair{" << p.first << ", " << p.second << "}"; return os; } template <typename other> static inline tag_ostream operator<<(tag_ostream os, other const& o) { os.get() << o; return os; } }
see live on coliru, prints:
std::pair{42, i'm gonna try} std::pair{1729, science}
Comments
Post a Comment