Boost logo

Boost :

From: Aleksey Gurtovoy (alexy_at_[hidden])
Date: 2001-07-30 06:41:43


David Abrahams wrote:
> > A few minor problems that I see:
> >
> > 1) Library author(s) should always remember to use
> > unqualified names for dispatching functions (begin(s, boost::tag)),
> > and qualified names for top-level interface functions
> > (boost::begin(s)) when they are used internally by the library
> > itself.
>
> Examples, please, and reasoning? I don't understand what you're
> saying above.

Sorry for being unclear. I'll try to explain what I meant. Suppose I am a
library author that decided to use your technique to provide my users a way
to specialize library's algorithms for their own class templates; so, I
write:

namespace lib {

struct tag {};

template<class T>
int capacity(T const& t, lib::tag)
{
    return t.capacity();
}

template<class T>
int capacity(T const& t)
{
    return capacity(t, lib::tag());
}

template<class T>
bool is_large_enough(T const& t, lib::tag)
{
    return capacity(t) > 100;
}

template<class T>
bool is_large_enough(T const& t)
{
    return is_large_enough(t, lib::tag());
}

} // namespace lib

and my library user write this:

#include "lib/capacity.hpp"
#include <utility>

namespace her {

struct something;
std::pair<int, int> capacity(something const&);

struct something
{
    friend int capacity(something const& s, lib::tag)
    {
        return her::capacity(s).first;
    }
};

} // namespace her

int main()
{
    her::something s;
    lib::capacity(s);
    if (lib::is_large_enough(s))
    {
    }
}

which (clearly :) doesn't compile:

"lib/capacity.hpp", line 39: error #349: no operator ">"
          matches these operands
            operand types are: std::pair<int, int> > int
      return capacity(t) > 100;
                         ^
          detected during:
            instantiation of "bool lib::is_large_enough(const T &, lib::tag)
                      [with T=her::something]" at line 45
            instantiation of "bool lib::is_large_enough(const T &) [with
                      T=her::something]"

Ok, I missed 'lib::' qualification in "bool lib::is_large_enough(const T &,
lib::tag)", no big deal, just add it here and check if it's missed anywhere
else:

namespace lib {

// ...

template<class T>
bool is_large_enough(T const& t, lib::tag)
{
    // add 'lib::' here
    return lib::capacity(t) > 100;
}

template<class T>
bool is_large_enough(T const& t)
{
    // here too? NO!!
    return is_large_enough(t, lib::tag());
}

} // namespace lib

Of course, all this example can be answered by "you better know what you are
doing" :), and I agree. My only concern is that even if you know, it's easy
to make a mistake, and if you did, compiler won't point you to it
(immediately).

Aleksey


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk