TJ Seabrooks
TJ Seabrooks

Reputation: 20733

Can the result of a function call be used as a default parameter value?

Is there a good method for writing C / C++ function headers with default parameters that are function calls?

I have some header with the function:

int foo(int x, int y = 0);

I am working in a large code base where many functions call this function and depend on this default value. This default value now needs to change to something dynamic and I am looking for a way to do:

int foo(int x, int y = bar());

Where bar() is some function that generates the default value based on some system parameters. Alternatively this function prototype would look like:

int foo(int x, int y = baz.bar());

Where baz is a function belonging to an object that has not been instantiated within the header file.

Upvotes: 7

Views: 720

Answers (8)

Don Wakefield
Don Wakefield

Reputation: 8852

In the standard, section 8.3.6 (Default arguments), paragraph 5, they give an example using just this approach. Specifically, it calls out that default arguments are expressions, so a function call applies, albeit with restrictions such as name lookup and type compatibility.

In my workplace, we've used signatures like this:

void An_object::An_object(
  const Foo &a,
  const Bar &b,
  const Strategem &s = Default_strategem()
);

to allow clients to override a behavior in a class constructor. It came in handy for conditional behavior which affected performance of a translator...

Upvotes: 4

Paul Nathan
Paul Nathan

Reputation: 40319

Tangential, but that looks to me like it'd introduce dependence issues down the road. I'd go with stbuton.myopenid.com's approach.

Upvotes: 2

Charlie
Charlie

Reputation: 45072

It should be perfectly valid to call a global function or reference a global object in this context, as long as the declaration of the function/object is in scope. It may or may not be advisable (in terms of good design), but it should work.

Upvotes: 1

Joe
Joe

Reputation:

Try making bar() a static member function. This will allow any part of the program which has such a static class in scope to access it. For example:

class Foo { public:

static int bar(); };

Then you would declare:

int foo(int x, int y = Foo::bar());

If you need different objects then pass in the instance of the object instead.

Upvotes: 0

user21714
user21714

Reputation: 5951

What's wrong with simply removing the optional parameter in the first declaration and providing a single parameter overload?

int foo(int x)
{
    Bar bar = //whatever initialization
    return foo(x,bar.baz());
}

int foo(int x,int y)
{
  //whatever the implementation is right now
}

I think this tends to be much cleaner and more flexible than trying to use some dynamic default value.

Upvotes: 6

Tim Sharrock
Tim Sharrock

Reputation: 111

I would use two overloaded functions:

int foo(int x, int y);

int foo(int x){return foo(x,bar);}

If you allow the forwarding function to be inlined, then the performance penalty is likely to small to zero. If you keep the body of it out of line in a non-header file there may be a performance cost (likely to be small), but much more flexibility in implementation and reduced coupling.

Upvotes: 7

Dima
Dima

Reputation: 39429

Go figure! It does work. Default arguments in C++ functions

Upvotes: 7

Lev
Lev

Reputation: 6667

Yes. What you've written works.

Upvotes: 6

Related Questions