Boost logo

Boost :

From: George A. Heintzelman (georgeh_at_[hidden])
Date: 2002-10-29 10:25:04

I went back and did a little more homework and found a few things out
which I think may have some implications for how we ought to organize
boost namespaces. My conclusion is that we probably ought to move boost
classes which are intended to be derived from by the user into
sub-namespaces which are brought into boost proper with using
declarations. This will inhibit Koenig lookup on the whole of boost for
user classes derived from these classes.

More detail on my thinking follows:

> From: "George A. Heintzelman" <georgeh_at_[hidden]>
> > namespace MyNS {
> > class Iterator: public boost::bidirectional_iterator_helper<...> {
> > };
> >
> > // I need some utility functions on the iterators:
> > int type(Iterator it);
> > };
> >
> > int main() {
> > Iterator it;
> > type(it);
> > }

> > `template<class T> class boost::type' is not a function, conflict with
> `int MyNS::type(MyNS::Iterator)' in call to `type'

> > Is there anything I (or boost) can do?<
> Yes, you can rename type() to something less collision prone. Functions that
> are intended to be used via argument dependent lookup must have distinctive
> names. "iterator_type" would be better, but probably not enough; use
> something more descriptive.

I don't like this answer. I understood that the idea of Koenig lookup
was to allow me to use those kinds of short names without having to say
myprefix_shortname(iterator) every time. In my case in particular, I am
replacing pointers with a new iterator type where we had functions
type(Record *) now getting replaced by type(Iterator), and type() isn't
the only name involved (I'd have to rename all the others for
consistency), so it's not a feasible solution for me.

So I went back to the standard and noticed that arg-dependent lookup
does *not* follow unnamed namespaces or using declarations in order to
look things up. So as a bit of a hack I tried changing boost/type.hpp
as so:

namespace boost {
  // Just a simple "type envelope". Useful in various contexts, mostly
to work
  // around some MSVC deficiencies.
  namespace type_detail {
    template <class T>
    struct type {};
  using namespace type_detail;

This doesn't cause anything in boost not to find boost::type when it
needs it (as far as I can tell, anyway), but it does inhibit Koenig
lookup from conflicting on it.

I didn't use the unnamed namespace, because that would lead to
different instantiations of boost::type in different translation units,
something I thought people might not want; however it also allowed my
code to compile. I didn't use boost::detail, because that would bring
in all the other names in boost::detail. Using 'using
type_detail::type;' also didn't work with g++ 3.2, though it worked
with Intel's compiler v7 beta. I'm not sure which one is right, though
I suspect Intel is (I'll be submitting a bug report to the gcc people
if I convince myself of that).

However, I didn't like the idea of having to dig through boost to
figure out which names ought to be protected from Koenig lookup.
Instead, we ought to prevent Koenig lookup from searching boost for the
user classes derived from boost classes, but we may want other
interfaces specific to those classes. For that, another option which
seems to be feasible would be to put class templates which are intended
to be derived from (such as bidirectional_iterator_helper) in their own
sub-namespaces, which are then brought back into boost visibility with
using declarations. In a test, for example, this seems to work, where
it fails without the foo::sub namespace:

namespace foo {
  namespace sub {
    template <class T>
    class bar {
  using namespace sub;
  class base {
    int b;

namespace baz {
  struct X: public foo::base {
    int x;
  void bar(X x);

int main() {
  baz::X myx;

Am I way off base? I think this is something that boost could do to
make interfaces based around argument-dependent lookup more feasible.

George Heintzelman

Boost list run by bdawes at, gregod at, cpdaniel at, john at