简体   繁体   中英

Is there a portable literal suffix for int64_t and similar types?

I was trying to understand std::variant:

#include <cstdint>
#include <variant>

std::variant<int64_t, double> v;

I wanted to assign an int64_t variant: v = 5L; That compiles on x86_64 because int64_t is long. But it does not compile on arm, because int64_t is long long. The type deduction has now two equal choices between int64_t and double to convert my number to, so it declines. With variant<int64_t, string> I wouldn't even have noticed the conversion, because then there is only one available and the compiler would have accepted it.

Similar issue with: v = 5LL; Now arm / 32 bit is fine, but x86_64 not anymore.

I get this compiling on both platforms but this is (sometimes) a type conversion with potential side-effects I am not able to foresee: v = int64_t(5LL); . Without the LL I wouldn't even be able to express values outside 32bit int.

The INT64_C macro seems to be the most portable and safest way to express this: v = INT64_C(5); But this not nice to read and write anymore.

Is there a similar literal suffix like L/LL for int64_t that is portable?

No, there are no standard literals for fixed width integer aliases.

One potential workaround would be to use std::variant<long long, double> v; . Although long long theoretically isn't guaranteed to be exactly 64 bits (it may be wider, but not narrower), it is 64 bits on practically every system that supports long long today. The benefit is that long long of course has a standard literal. The potential drawback is that the size situation may theoretically change in future.

A more general solution is to give up on using a literal suffix, and instead use a cast: v = static_cast<int64_t>(5); .

Another solution is to create a user defined literal as shown in this answer linked in comments:

 constexpr std::int64_t operator "" _int64(unsigned long long v) { return static_cast<std::int64_t>(v); }

There is a proposal to add literals such as this to the standard library:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1280r2


On a related note, there is a proposal to add literals for std::size_t and std::ptrdiff_t . That proposal suggests core language literals instead of a standard library literals:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0330r3

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM