Скажем, у меня есть следующий класс:
template<typename T>
class val {
private:
std::shared_ptr<T> m_value, m_min, m_max;;
public:
val(T value, T min, T max) : m_value(std::make_shared<T>(value)), m_min(std::make_shared<T>(min)), m_max(std::make_shared<T>(max)) {}
val(T value) : m_value(std::make_shared<T>(value)), m_min(nullptr), m_max(nullptr) {}
public:
operator T() {
return *this->m_value;
}
val& operator=(const T& other) {
*this->m_value = other;
return *this;
}
std::shared_ptr<T> minimum() {
return this->m_min;
}
std::shared_ptr<T> maximum() {
return this->m_max;
}
};
Используется как таковой:
auto i = val(5);
auto f = val(64.f);
auto f_clamped = val(64.f, 0.f, 128.f);
Моя желаемая функциональность заключается в том, чтобы эта операция go как таковая:
auto f_clamped = val(64.f, 0.f, 128.f);
f_clamped = 32.f; // all good
f_clamped = 200.f; // f_clamped is now 128.f
Я пытался реализовать это в операторе равенства (=) класса следующим образом:
val& operator=(const T& other) {
T ret = other;
if (std::is_arithmetic<T>::value) {
if (this->m_min && this->m_max) {
T min = *this->m_min;
T max = *this->m_max;
if (ret > max)
ret = max;
if (ret < min)
ret = min;
}
}
*this->m_value = other;
return *this;
}
Но это не работает, потому что T, с точки зрения компилятора, не может предполагаться быть арифметическим c значением.
Как мне утверждать, что T - это арифметическое c значение, чтобы я мог выполнять арифметические c операции над ним?
Что-то вроде этого в порядке?
template<
typename T,
typename = typename std::enable_if<std::is_arithmetic<T>::value, T>::value
>
val& operator=(const T& other) {
T ret = other;
if (this->m_min && this->m_max) {
T min = *this->m_min;
T max = *this->m_max;
if (ret > max)
ret = max;
if (ret < min)
ret = min;
}
*this->m_value = other;
return *this;
}
```