
On 30 June 2012 14:21, Nathan Ridge <zeratul976@hotmail.com> 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() { foo(1); } // and later link to the One Definition of foo void foo(int x, int y) { cout << "x: " << x << " y: " << y << endl; } https://gist.github.com/3023854
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.