Boost logo

Boost :

Subject: Re: [boost] [range] treating N-ary function with N-1 default args as unary
From: Rowan James (rowanj_at_[hidden])
Date: 2012-06-30 10:00:19

On 30 June 2012 14:21, Nathan Ridge <zeratul976_at_[hidden]> wrote:

> > Some Boost.Range adaptors, such as 'transformed' or 'filtered', require
> > a unary function. The documentation does not formally define "unary
> > function", but it's pretty clear what it ought to be: a function (object)
> > that's callable with one argument.
> >
> > Thus, to me, the following is a perfectly valid unary function:
> >
> > int foo(int a, int b = 0);
> >
> > as it is callable with one argument.

Not really; it's still only called with two arguments, but the second is
generated at the call site with the specified value if only one is
specified. The default arguments are only part of the declaration; that's
why you can specify them locally if you're calling a library function with
the same arguments repeatedly:

#include <iostream>
using namespace std;

// #include <some header>
void foo(int x, int y);

// but we always use y = 2 with foo
void foo(int x, int y = 2);

int main()

// and later link to the One Definition of foo
void foo(int x, int y)
        cout << "x: " << x << " y: " << y << endl;

> >
> > However, Boost.Range does not accept such a function as an argument to
> > 'transformed' or 'filtered'.
> >
> > [snip]
> >
> > Would it be possible to treat N-ary functions with N-1 default arguments
> > as unary?
> To motivate this request a bit further, suppose 'foo' is a function in
> some library, so that I can't just replace it with two overloads, and
> consider possible workarounds:
> 1. range | transformed(bind(foo, _1, let_me_repeat_the_default_arg_here));
> 2. range | transformed([](let_me_write_out_the_type_of_foo's_argument_here
> x)
> { return foo(x); })
> The first requires repeating the library function's default argument, which
> introduces a risk of the actual behaviour becoming out of sync with the
> desired behaviour if the default argument used by the library changes.
> (Note that simply bind(foo, _1) will not work - it produces similar
> errors).
> The second is messy (and would be even more so in C++03) and requires
> writing
> out the potentially long type name of the function's argument.
> I can't think of anything better at the moment.
> Regards,
> Nate

I don't think this can be done generically; the function will get the
arguments as in the most recent declaration at some arbitrary point, so you
need to specify the point yourself; in this case, with the location of the
bind call.

I hope this is making sense, and that I'm using the correct terminology.

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