I want to disable a function for any compile-time evaluated argument (a literal, or something that comes from a constexpr expression). Is that possible?
For integers, it is possible to do the opposite use non-type template arguments, but that would also change the call syntax.
I am playing around with strict integers, that needs to be initiated somehow. Current rule for handling bad input:
If the source value is only known at runtime, and a narrowing cast would destroy the interpretation (not the bits), an exception is thrown
If the source value is known at compile time, and it wouldn't fit there should be a compilation error.
My idea was to disable the constructor that accepts a wider type for all constexpr arguments.
By strict, I mean that only value-preserving conversions are allowed:
Assume N >= M
int<M>
toint<N>
Always OKuint<M>
touint<N>
Always OK
For everything else:
- There should be a compilation error if the source value is known at compile-time.
- If the value is not known during compilation, see if a conversion would work properly, otherwise throw an exception.
For case (1), using the constexpr-throw trick does not work: Consider the following (non-constexpr context):
// Will compile, but it shouldn't. Instead of not compiling it will throw an exception.
int<16> foo(12345);
// Will compile. Whatever the type of some_value_from_outside is,
// check that it fits at runtime. If it does not, throw an exception.
int<16> thisIsFine(some_value_from_outside);
What would be ideal is overload resolution with respect to constexpr argument, which does not exists, so I am trying to find the best workaround.