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: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:
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 doint 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:
This might actually be the best option…