The secret is all in whether you declare the user-defined literal functions as constexpr
or not.
Compare this (normal execution-time function):
#include <iostream>
int operator "" _twice(unsigned long long num) { return num*2; }
int xyzzy = 7_twice;
int main () { std::cout << xyzzy << "\n"; return 0; }
With this (compile-time constant, the static_assert
works):
#include <iostream>
constexpr int operator "" _twice(unsigned long long num) { return num*2; }
int xyzzy = 7_twice;
int main () {
static_assert(7_twice == 14, "not compile time constant");
std::cout << xyzzy << "\n";
return 0;
}
Obviously, declaring a function constexpr
restricts all statements within to be constexpr
also, or compile-time constants; no random number shenanigans allowed.