Reputation: 20733
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
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
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
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
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
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
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