Boost logo

Boost :

From: Aleksey Gurtovoy (alexy_at_[hidden])
Date: 2002-01-30 12:58:38

Douglas Gregor wrote:
> > Yes, in fact, going this route would allow us to write a version of
> > 'function<>' class that would take _less_ space than the current
> > implementation (1 function pointer + 1 data pointer,
> > instead of current 2 function pointers plus + 1 function/data pointer).
> I'm not quite sure how you plan to do this. At the moment, function<>
> requires:
> - a "manager" function pointer that handles allocation,
> deallocation, and copying of the underlying function object
> - an "invoker" function pointer that handles calls to the
> function object
> - a data pointer that contains a pointer to the function object
> I can't quite see how to wipe out one of these pointers,
> except perhaps to use _really_ dirty tricks, like:

[clever code snipped]

Another way would be to make "manager" to handle everything, including
invocation. Of course, it'll increase the cost of the call.

> > So, returning to the original suggestion ('bind(&my:foo, this)'
> > optimization) - can we have it? :)
> Here's a start: by the end of this weekend, I promise to have
> the "stateless function objects" optimization implemented, and
> I'll try to get unbound member function pointers optimized as
> well

Thanks, looking forward to it!

> If there is some reasonable way to describe bind(&my::foo, this) with
> &my::foo as a compile-time constant (and therefore encode it
> as part of the type), I'm sure we can work it in without too much trouble.

Well, it looks like there is a way to describe it (obviously) - something
like 'mf0<void, my, &my::foo>(this)', but there is no way to hide the
ugliness behind something even close to simple 'bind(&my::foo, this)', at
least within the current language. Hmm.. what do you think of the following
alteration to 14.5.5 [temp.fct]:

3 A non-type _template-parameter_ of a function template can be used in
place of the function _parameter-declaration_. A _template-argument_ for a
such _template-parameter_ can be deduced from a corresponding function call
expression, given that it satisfies the requirements in 14.3.2. [Example:

    template<class T, bool (T::* f)()> bool invoke(f) { return f(); }

    template<int n, int m> struct power_t { /* compile-time computation of
pow(n, m) */ };
    template<int n, int m> double pow(n, m) { return power_t<n,m>::value; }

    int main()
        extern bool foo();
        bool (*ptr)() = &foo;

        invoke(&foo); // ok, 'f' is deduced from the call
        invoke(ptr); // error, not a '&id-expression' (see 14.3.2)

        int i = 10;
        pow(10,2); // ok
        pow(i,2); // error, 'i' is not an integral constant-expression

--end example]

(See section 10.14 of C&E "Generative Programming" book for the original
'power' function template example)

Obviously, the change would bigger than just the above paragraph (which is
just a sketch), but IMO it would worth it. In particular, it would allow us
to implement all the optimizations that have been proposed in this thread.
Do you think it's worth pursuing? IMO it certainly falls under the category
of extensions that "make C++ a better language for [generic] library
building" :).


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