Boost logo

Boost :

From: Douglas Gregor (gregod_at_[hidden])
Date: 2001-06-27 09:59:29

On Wednesday 27 June 2001 06:54, you wrote:
> Doug,
> I've putting together some test cases for the new macros that function
> added to config.hpp: and I'm struggling to understand
> First off, this is defined for Borland compilers, but all the function
> tests compile OK with bc 5.51: am I missing something here?

It's essentially for optimization. For instance, the following code:
function<int, int> f;
f = negate<int>(); // #1

At #1, Borland will choose to construct a function<int, int> object from the
negate<int> object, then call f's copy assignment operator. This results in
two allocations of "negate<int>" objects and one deallocation, so it is
inefficient. At the time, I had though this was a name lookup problem (it
wasn't finding the templated operator= from the base class), so I added the
macro, which "fixed" the call. Now it didn't create the temporary (that's

Well, I was wrong and Borland was right. The best overload candidate is
indeed to use f's copy assignment operator after creating a temporary
function<int, int> object. This was very surprising to me, so I'll explain

You might be sorry you asked :)

Consider this little tidbit of overload resolution:

struct Foo {
  template<typename T> Foo& operator=(const T&);

struct Bar : public Foo {
  template<typename T> Bar(T);
  Bar& operator=(const Bar& other);

Bar b;
b = 5;

So what happens at b=5? Clearly the candidates are either:
1) a call to Foo::operator=(T). This requires:
        a) b is converted to type Foo& (Rank: Conversion, table 9)
        b) 5 is copy-initialized. Since the types are equal except for cv-quals, it
binds directly (8.5.3p5) and is therefore considered the identity conversion
(Rank: Exact Match,

2) a call to Bar::operator=(const Bar&)
        a) no conversions required, Rank: Exact Match
        b) other is copy-initialized. Since int can be implicitly converted to Bar
and then to const Bar&, the reference binds directly. Rank: Exact Match (!)

So #2 is better than #1.

What's the resolution? BOOST_NO_DEPENDENT_BASE_LOOKUP is the wrong name for
the macro for sure - it isn't a compiler deficiency at all. Most likely the
macro should be removed and I'll work on a way to deal with the copy
efficiency problems.

> Secondly, you do realise that members of template base classes are not
> visible to derived classes anyway - you have to use either:
> base_type::member_name
> (which breaks VC6), or use:
> this->member_name
> which seems to work everywhere.
> If I've misunderstood the intent of this macro (quite likely!), apologies.
> - John Maddock


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