From the 2017 C++ standard, section 11.3.6, para 9
A non-static member shall not appear in a default argument unless it appears as the
id-expression of a class member access expression (8.2.5) or unless it is used to form a pointer to member (8.3.1).
All other C++ standards (before and since) have a similar statement, although the wording and section numbers vary. Neither of the "unless" points in the above are applicable in this case.
It is notionally possible (since C++17) to use std::optional
(from header <optional>
) to avoid the overload, as follows.
#include <optional>
class A
{
int data;
int _default = 0;
public:
// other members omitted
void set(std::optional<int> data = std::optional<int>())
{
this->data = data.has_value() ? data.value() : _default;
};
};
or (as suggested by Jarod42 in comments)
void set(std::optional<int> data = std::nullopt)
{
this->data = data.value_or(_default);
};
I use the word "notionally" in the above because, personally, I would simply use two overloads. It is (arguably) easier for a mere mortal to understand and works with all C++ standards (not just since C++17)
void set(int data){ this->data = data; }
void set(){ set(this->_default); }