|
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