Я создал этот класс, чтобы иметь значение любого типа, которое либо фиксируется, либо пересчитывается каждый раз, когда оно используется:
template <typename T>
class DynamicValue {
private:
std::variant<T, std::function<T()>> getter;
public:
DynamicValue(const T& constant) : getter(constant){};
template <typename F, typename = std::enable_if_t<std::is_invocable_v<F>>>
DynamicValue(F&& function) : getter(function) {}
DynamicValue(const T* pointer) : DynamicValue([pointer]() { return *pointer; }) {}
DynamicValue(const DynamicValue& value) : getter(value.getter) {}
~DynamicValue() {}
DynamicValue& operator=(const DynamicValue& value) {
getter = value.getter;
return *this;
}
operator T() {
return getter.index() == 0 ? std::get<T>(getter) : std::get<std::function<T()>>(getter)();
}
};
Я также написал следующую фиктивную структуру, чтобы продемонстрировать свою проблему:
struct A {
int b;
};
Проблема в том, что в идеале я мог бы обрабатывать любой DynamicValue<T>
, как если бы он был типа T
. Поэтому, если бы мне нужно было создать новое значение (DynamicValue<A> a = A{1};
), я смог бы выполнить a.b
и получить атрибут b
значения, вычисленного a
. Однако я получаю следующую ошибку:
«класс DynamicValue» не имеет члена с именем «b»
Вы можете попробовать живой пример здесь.
Мой вопрос: есть ли способ решить эту проблему, или я должен принять синтаксис ((A) a).b
? Я думал о перегрузке каждого оператора для достижения своей цели, но это решение не будет работать с оператором .
(и другими), который не перегружается и может иметь свои проблемы.