I have a type that takes a value, checks it against the type's parameters, and from that point on allows the value to carry around that check as an invariant. The type also has a number of operations associated with it that create new values of that type. All those operations are defined so that the check is not needed. There is no way once the user's value is in the type to ever have an invalid value of that type.
What I need is two constructors: one internal and one external. The external constructor should perform the check, while the internal constructor should not. They otherwise have the same parameters, the only difference is the check, which is the main issue. The check is avoided for performance reasons. Below is a mocked up example.
#include <stdexcept>
template <int limit>
class ClippedValue;
template <int limit>
void check(ClippedValue<limit> v) {
if (std::abs(v.value) > limit) {
make_user_solve_P_eq_NP();
throw std::range_error("Given value exceeds available range");
}
}
template <int limit>
class ClippedValue {
public: // external constructor
constexpr ClippedValue(int a) : value(a) { check(*this); }
private: // internal constructor
constexpr ClippedValue(int a) : value(a) {}
public: // members
const int value;
public: // friends
template <int A, int B>
friend constexpr ClippedValue<A + B> operator+ (ClippedValue<A> a, ClippedValue<B> b);
}
template <int A, int B>
constexpr ClippedValue<A + B> operator+ (ClippedValue<A> a, ClippedValue<B> b) {
return a.value + b.value;
}
The above doesn't compile, the two constructors are identical.
Aucun commentaire:
Enregistrer un commentaire