I'm trying to add debug instrumentation in C++. I want to probe all changes to a variable. To do that, I'm using the c++20 std::source_location::current() feature, like this member function:
void DoubleWithProbe::set(double newValue, std::source_location loc = std::source_location::current())
{
std::cout << "Changed: new = " << newValue << ", old = " << m_value
<< " (" << loc.file_name() << ":"
<< loc.line() << ")" << std::endl;
m_value = newValue;
}
However, this requires the caller to use a set function. If I try to use operators, the pattern fails:
operator double(std::source_location loc = std::source_location::current()) const
{
std::cout << "Accessed: value = " << m_value <<
<< " (" << loc.file_name() << ":"
<< loc.line() << ")" << std::endl;
return m_value;
}
DoubleWithProbe& operator=(double newValue, std::source_location loc = std::source_location::current())
{
...
}
These are both illegal because operator double may not have arguments and operator= must have only one argument. For operator=, I've found this workaround:
struct DoubleAndLoc
{
double m_val;
std::source_location m_loc;
// not explicit.
DoubleAndLoc(double val, std::source_location loc = std::source_location::current())
: m_val(val), m_loc(loc)
{
}
};
DoubleWithProbe& operator=(DoubleAndLoc newValue)
{
...
}
This is probably ok for doubles, but for strings, this would quickly run into double-conversion issues.
Is there any way to make operator double() work, and any way to make operator=() work more cleanly?
A working example is at https://godbolt.org/z/4Ea1sPT1n.