I want to introduce strong types with error checking at compile time. For my chrono type, I noticed literals are silently narrowed when the underlying type changes from int64_t to int32_t, leading to overflows. So I introduced an explicit check.
However this check is not checked at compile time even for constant parameters, like delay_t {10s}, which cannot be represented.
#include <chrono> #include <cstdint> #include <stdexcept> struct delay_t { std::chrono::duration<int32_t, std::nano> value {}; constexpr explicit delay_t(std::chrono::duration<int64_t, std::nano> delay) : value {delay} { if (value != delay) { throw std::runtime_error("delay cannot be represented."); } }; }; auto foo(delay_t delay) -> void {} auto main() -> int { using namespace std::chrono_literals; foo(delay_t {10s}); // here I want a compile time error, // but I get a runtime error. return 0; } This unfortunately compiles and leads to a runtime error. I verified that the literal operator"" s is a constexpr and it works using consteval in the delay_t constructor. I also want to use the type with runtime values, so that's not an option.
How can I tell the compiler above to evaluate constant literals like time_t {10s} at compile time? I am using C++20.
int32_tfor nanosecond precision?