C ++ 11 user literals

I am learning C ++ 11 and I'm interested in custom literals. So I decided to play a little with this. Some languages โ€‹โ€‹have syntax like this:

int n = 1000_000_000; 

I tried to simulate this function in C ++ 11.

 inline constexpr unsigned long long operator "" _000 (unsigned long long n)noexcept { return n * 1000; } inline constexpr unsigned long long operator "" _000_000 (unsigned long long n)noexcept { return n * 1000*1000; } inline constexpr unsigned long long operator "" _000_000_000 (unsigned long long n)noexcept { return n * 1000*1000*1000; } int main(){ constexpr auto i = 100_000; // instead of 100000 constexpr auto j = 23_000_000; // instead of 23000000; } 

But for the general case, I could not imitate it, i.e.

auto general_case = 123_456_789; // cannot compile

My question is: "Can I simulate for a general case, as described above, using C ++ 11?".

+7
c ++ c ++ 11 user-defined-literals
source share
1 answer

This is not possible with custom literals in the C ++ 11 language version, as of now. Custom literals support a limited parameter format, it seems they don't support the right parameter, the chain, and also the problem of representing numbers that start with 0 as actual numbers. So this is not an option.

The current approach defines _000, etc. as stand-alone literals, so the compiler will only work with them and with no one else. This is not like _ - it is an operator, and 000 is some parameter that you can work with, unfortunately.

You can use letter suffixes instead.

 long long constexpr operator"" K (long double n) { return n * 1000; } long long constexpr operator"" M (long double n) { return n * 1000000; } long long constexpr operator"" G (long double n) { return n * 1000000000; } 

And then:

 0.05M == 50000; 123.232K == 123232 1.000000001G == 1000000001 

Undoubtedly, the last case thwarted the target, because again you have many zeros without a visual indication ... So, you can go for something like:

 1.G + 1 == 1000000001 // much clearer 1 billion + 1 

This makes it a little ugly, since the literal expects a real number and will not work with an integer unless you define an extra literal, just to use it with integers. Then you can just use 1G instead.

In addition, this approach is likely to trigger compiler warnings, apparently the C ++ group wants to reserve all suffixes that are not preceded by underscores for โ€œfuture usesโ€. If you want the warnings to go, use _K _M and _G instead.

EDIT: I deleted the initializer list solution because it produces invalid results with numbers, such as 010, which are treated as octal and ruined the calculations.

+4
source share

All Articles