Boost logo

Boost :

From: David Abrahams (dave_at_[hidden])
Date: 2002-08-02 13:10:04


Hi All,

Joel and I are working on a library problem, and he tried something neither
of us ever expected to work. Surprise! It works with most of our
more-capable compilers (including recent Comeau). However, we can't find
any justification for it in the standard. If we're not just exploiting a
compiler bug here, it could have major implications for Boost.Function,
Boost.Lambda, et. al. Can anyone point us at standard text which explains
this? The main issue here is that it looks as though the existence of
default arguments is getting passed along with a function pointer(!) used
as a function argument.

Any clues? No wild speculation, please: pointers to standard text is what
we're after. Thanks:

#include <iostream>
using namespace std;

///////////////////////////////////////
template <typename F, typename RT>
struct f_stub_0 {

    F f;
    f_stub_0(F f_) : f(f_) {}
    RT operator()() const { return f(); }
};

///////////////////////////////////////
template <typename F, typename RT, typename A0>
struct f_stub_1 {

    F f;
    f_stub_1(F f_) : f(f_) {}
    RT operator()(A0 a0) const { return f(a0); }
};

///////////////////////////////////////
template <typename F, typename RT, typename A0, typename A1>
struct f_stub_2 {

    F f;
    f_stub_2(F f_) : f(f_) {}
    RT operator()(A0 a0, A1 a1) const { return f(a0, a1); }
};

///////////////////////////////////////
template <typename F>
struct f_stubs;

///////////////////////////////////////
template <typename RT, typename A0, typename A1>
struct f_stubs<RT(A0, A1)> {

    template <typename F>
    static f_stub_0<F, RT>
    f0(F f)
    { return f_stub_0<F, RT>(f); }

    template <typename F>
    static f_stub_1<F, RT, A0>
    f1(F f)
    { return f_stub_1<F, RT, A0>(f); }

    template <typename F>
    static f_stub_2<F, RT, A0, A1>
    f2(F f)
    { return f_stub_2<F, RT, A0, A1>(f); }
};

///////////////////////////////////////
//
// TEST
//
///////////////////////////////////////

int
foo(int a = 1, int b = 2)
{ return a + b; }

///////////////////////////////////////
int
main()
{
    typedef f_stubs<int(int a, int b)> f_stubs;

    cout << f_stubs::f0(foo) () << endl;
    cout << f_stubs::f1(foo) (10) << endl;
    cout << f_stubs::f2(foo) (10, 20) << endl;
}

-----------------------------------------------------------
           David Abrahams * Boost Consulting
dave_at_[hidden] * http://www.boost-consulting.com


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