I have a number. How to get a type that can store this number multiplied by 2 if the number is not of the “maximum” type? For example, a number i type __int32 , then 2*i can always be stored in __int64 . How do I know if I need __int64 ?

  • How do you know that in int 32 bits? - vp_arth
  • 1. The binary logarithm of the received number shows what digit capacity this number needs. - nick_n_a
  • @nick_n_a can write a meta function? - user238446
  • @vp_arth let it be __int32 then - user238446
  • one
    Give the code snippet where you have a problem - so we will not guess your idea. - nick_n_a

2 answers 2

Well, offhand, you can simply manually create (platform-dependent) mapping of type sizes to the next size type

 template <size_t N> struct next_type_impl; template <> next_type_impl<8> { // Предполагая 16-битный `short` typedef short signed_type; typedef unsigned short unsigned_type; }; template <> next_type_impl<16> { // Предполагая 32-битный `int` typedef int signed_type; typedef unsigned unsigned_type; }; // И т.д. template <typename T> next_type { typedef typename next_type_impl<sizeof(T)>::signed_type signed_type; typedef typename next_type_impl<sizeof(T)>::unsigned_type unsigned_type; }; 

And further in the code

 next_type<decltype(i)>::signed_type larger_i; 

All this can be realized more elegantly and more flexibly, but the approximate idea is as follows.


For example, once you set up a sequence of integer types with your hands, you can automatically choose a larger type of platform if it exists

 #include <type_traits> #include <iostream> template <typename T> struct next_int { typedef T type; }; template <> struct next_int<signed char> { typedef short type; }; template <> struct next_int<short> { typedef int type; }; template <> struct next_int<int> { typedef long type; }; template <> struct next_int<long> { typedef long long type; }; /**********/ template <typename T> struct next_larger_int; template <typename T, bool stop = false> struct next_larger_int_cond { typedef typename next_larger_int<typename next_int<T>::type>::type type; }; template <typename T> struct next_larger_int_cond<T, true> { typedef T type; }; template <typename T> struct next_larger_int { typedef typename next_int<T>::type next; typedef typename next_larger_int_cond<next, (sizeof(next) > sizeof(T)) || std::is_same<T, next>::value>::type type; }; int main() { std::cout << sizeof(next_larger_int<signed char>::type) << std::endl << sizeof(next_larger_int<short>::type) << std::endl << sizeof(next_larger_int<int>::type) << std::endl << sizeof(next_larger_int<long>::type) << std::endl << sizeof(next_larger_int<long long>::type) << std::endl; } 
  • Yes, this is what I want, but is it possible to somehow get the required type without specifications by the number of bits or is it impossible in principle? - user238446

In general, C ++ says nothing about the specific size of the types. So int may also be the same as __int64 .

Unless look in <cstdint> types with the exact sizes.

  • Why it is not done in any cross-platform program? - user238446
  • @ user238446: Such questions in cross-platform programs are usually not solved "automatically" through metaprogramming, but manually, through a set of typedef for numeric types. Type let us have the data_type type to store the main data and the type mul_data_type to perform the multiplication between the two data_type . The correct types are set by hand for each platform. - AnT