Update: I posted my own answer below And there's a longer version of this matter here: http://scrupulousabstractions.tumblr.com/post/38460349771/c-11-type-safe-use-of-integer-user-defined-literals
Question:
I've made a simple constexpr
user defined literal _X
that gets the value as an unsigned long long (that's how numeral user defined literals work: http://en.cppreference.com/w/cpp/language/user_literal), and then I make sure that the value fits in a signed long long.
It all works well (too big values cause compilation error), but only when I explicitly create a variable such as
constexpr auto a= 150_X;
If instead I write something typical like
cout << 150_X << endl;;
the tests are not performed at compile time.
Are constexpr functions only executed at compile time if they are assigned to a constexpr variable? (I could not find that in the standard)
Is it possible to achieve the safe behaviour of
_X
that I'm looking for?
Full example:
#include<iostream>
#include<stdexcept>
inline constexpr long long testConv(unsigned long long v) {
return (v > 100 ) ? throw std::exception() : v;
} // will eventually use actual limit from numeric_limits
inline constexpr long long operator "" _X(unsigned long long f) {
return testConv(f) ;
}
int main(){
constexpr auto a= 5_X;
std::cout << a << std::endl;
std::cout << 200_X << std::endl; // This bad literal is accepted at compile time
constexpr auto c=250_X; // This bad literal is not accepted at compile time
std::cout << c << std::endl;
}
oh, for reference: I used gcc4.7.2.