Вам не нужно перегружать все операторы, как предлагали другие, хотя этот подход обеспечивает максимальный контроль, поскольку выражения, включающие объекты типа constrained<T>
, останутся этого типа.
Альтернативой может быть только перегрузка мутирующих операторов (=, + =, - =, * =, / =,% =, & =, | =, ^ =, << =, >> =, pre и post ++, pre и post -) и обеспечить пользовательское преобразование в T
:
template<typename T>
class constrained {
... // As before, plus overloads for all mutating operators
public:
operator T() const {
return value;
}
};
Таким образом, любое выражение, включающее объект constrained<T>
(например, x + y
, где x
- это int
, а y
- constrained<int>
), будет rvalue типа T
, который обычно больше удобно и эффективно. Безопасность не теряется, потому что вам не нужно контролировать значение любого выражения , связанного с объектом constrained<T>
- вам нужно проверять ограничения только тогда, когда T
становится constrained<T>
, а именно в конструкторе constrained<T>
и в любом из операторов мутации.