c++ - Is it bad style to overload operators on std containers in global scope? -
i had problem arise:
// a.h #include <vector> typedef std::vector<unsigned char> buffer; buffer &operator+=(buffer &a, buffer const &b); // b.h namespace bar { struct qux { }; qux &operator+=(qux &a, qux const &b); } // foo.cpp #include "a.h" #include "b.h" // comment out, error goes away namespace bar { void foo() { buffer a, b; += b; // error } } the problem (as described here) a += b; fails compile because bar::operator+=(qux&, qux const &) hides ::operator+=; , adl not find ::operator+ because adl searches namespace std; in case.
this icky because problem appears if b.h included -- b.h apparently has nothing buffer . code shouldn't break depending on whether include header.
(actually discovered when changing compilers, previous compiler using did name lookup incorrectly , accepted code).
my question is: overload in a.h bad idea because of issue?
i work around issue having b.h using ::operator+=; inside namespace bar seems pretty hacky, there better option?
the easiest, safest, reusable approach can think of have 1 of += arguments of type in operator's namespace:
template <typename t> struct argumentref { argumentref(t& t) : t_(t) { } operator t&() { return t_; } operator const t&() const { return t_; } t& t_; }; typedef std::vector<unsigned char> buffer; buffer &operator+=(argumentref<buffer> a, buffer const &b) { } that said, inheritance - while controversial in c++ circles due non-virtual destructor in vector - fine imho, if aren't exposing buffer in api wider use, , not using dynamically allocated instances in code designed own , handle base class.
Comments
Post a Comment