C++ Logo

std-proposals

Advanced search

Re: Proposal: template function solution to Pythonic optional function arguments

From: Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]>
Date: Sun, 19 Jul 2020 12:34:55 -0400
On Sun, Jul 19, 2020 at 11:45 AM Ed Bird via Std-Proposals <
std-proposals_at_[hidden]> wrote:

> Hi,
>
> I am not sure if this is the correct email address to which I should
> direct this enquiry
>

It is (I mean I don't know a better place, except for /r/cpp or the Cpplang
Slack or I think there's a Discord now).

[...] In my view, if a function has an optional argument, then it should be
> treated similarly to how template classes are treated. In other words, this
> is an example of a case where one block of code should produce multiple
> blocks of executable code when compiled.
>

But we already have function overloading, which gives you the same thing
with a much simpler syntax.
Your example code could be (in C++98 and later)

void draw(int parameter) {
    do_draw(parameter);
}
void draw(int parameter, int mode) {
    do_draw(mode == 1 ? -1 : parameter);
}

We also have default function arguments, although I recommend against their
use:
https://quuxplusone.github.io/blog/2020/04/18/default-function-arguments-are-the-devil/

void draw(int parameter, int mode = 42) {
    do_draw(mode == 1 ? -1 : parameter);
}

Notice that in your specific case, `mode` has only two meaningful values —
"1" and "not 1" — and so it should probably be a `bool`, not an `int`.

I don't personally like the syntax of using `#if` to achieve the
> anticipated result, but this is just my personal opinion
>

Indeed, you can't use preprocessor macros for this, because the C
preprocessor doesn't know anything about functions or variables or anything
like that. That's also why C++ templates use the dedicated `template`
keyword, instead of some weird code-duplicating macro magic.

I actually introduced a bug due to the fact that I had a long list of
> default parameters, and missed one when calling the function. An implicit
> cast from int to bool was responsible for the function behaving differently
> to how I expected. I fixed this by putting in the missing arguments, of
> course.
>

Indeed. Default function arguments are the devil.


> But it wouldn't have happened if I could have done `draw(1, mode=-1);`
>

Even better for your rapid-prototyping work:

    int draw(int param);
    int draw_with_mode(int param, int mode);

    draw_with_mode(1, -1);

with no default function arguments at all. This way you can't accidentally
forget the mode; if you try to call `draw_with_mode(1)` you get a compiler
error.
Of course I can't stop you from spelling it `draw2` instead of
`draw_with_mode`. ;)

HTH,
Arthur

Received on 2020-07-19 11:38:24