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