#include <iostream>
class IdProvider {
static int count;
private:
IdProvider(){}
public:
static IdProvider& Instance() {
static IdProvider instance;
return instance;
}
int Next() {
return ++count;
}
};
int IdProvider::count = 0;
template <typename T> class TracingValue {
private:
T m_Val;
int m_Id;
private:
void LogStackTrace() {}
public:
int Id() const { return m_Id; }
TracingValue &operator=(const TracingValue &other) {
LogStackTrace();
m_Val = other.m_Val;
std::cout << "id: " << this->Id() << " new value: " << m_Val
<< " from id: " << other.Id() << std::endl;
return *this;
}
TracingValue &operator=(const T &val) {
LogStackTrace();
m_Val = val;
std::cout << "id: " << this->Id() << " new value: " << m_Val << std::endl;
return *this;
}
TracingValue(const T &val):m_Id(IdProvider::Instance().Next()),m_Val(val) {
std::cout << "id: " << this->Id() << " constructed with value: " << val << std::endl;
LogStackTrace();
}
TracingValue(const TracingValue &other):TracingValue(other.m_Val) {
std::cout << "id: " << this->Id() << " constructed from id: " << other.Id() << std::endl;
}
TracingValue():TracingValue(T()) { LogStackTrace(); }
operator T() const { return m_Val; }
};
int main() {
TracingValue<double> d;
d = 3.;
d = 42.;
double x = d - 2.;
std::cout << x << std::endl;
TracingValue<double> other_d(d);
TracingValue<double> another_d;
another_d = other_d;
}