I want to achieve something like this:
class C
{
int m_nVal;
public:
C(int nVal) : m_nVal(nVal){}
void foo(int nVal = m_nVal)
{
// use nVal, if provided; otherwise use m_nVal
}
};
C c(1);
c.foo(); // use 1
c.foo(2); // use 2
This is not possible as C++ standard says:
a non-static member shall not be used in a default argument
Options I have are:
(1) Overload foo()
:
class C
{
int m_nVal;
public:
C(int nVal) : m_nVal(nVal){}
void foo()
{
// use m_nVal
}
void foo(int nVal)
{
// use nVal
}
};
(2) Use static member:
class C
{
static int m_nVal;
public:
void foo(int nVal = m_nVal)
{
// use nVal, if provided; otherwise use m_nVal
}
};
I don't want to make m_nVal
static member so option 1 seem the only one.
Are there any other ways to achieve this?
There are other alternatives if you are willing to change the interface. You can use boost::optional
:
// untested:
void foo( boost::optional<int> val = boost::optional<int>() ) {
int value;
if ( val ) value = *val;
else value = m_val;
// Now use `value` in the function
}
If you cannot use boost, you can write your own nullable wrapper. You just need to store the type (int
) and a flag that determines whether it is set or not.
The next option is using a pointer to mark that the argument is optional:
void foo( int *pval = 0 ) {
int value = (pval? *pval : m_val);
// use value from here on
}
But the option with the pointer inhibits the use of rvalues as arguments to the function (i.e. you need a proper variable to call the function, you cannot do foo(1)
but rather need to do int x = 1; foo( &x );
, which is kind of a pain).
Finally you can use your approach of offering two overloads, one that takes the argument and one that doesn't and just forwards to the first:
void foo( int val ) {
// actual implementation
}
void foo() {
foo( m_val );
}
This might actually be the best option...
The two options aren't equivalent. Making a member static
shouldn't be a decision made on whether you want to use it as a default to a method or not.
If m_nVal
is logically bound to the class, and not an instance, make it static
.
If m_nVal
is specific to each object of the class, don't, and use the first option.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With