Is overloading all major integer types sufficient to capture all integers?

Let's say I have overload functions for all standard integer types:

void foo( char );
void foo( signed char );
void foo( short );
void foo( int );
void foo( long );
void foo( long long );
// .... all unsigned variants as well

Is it possible that these overloads cannot find the proper overload for types like int8_tor something like that? Is there any way to handle such overloads?

What about links?

To clarify the question: this is related to the discussion of this question. Why is int8_t read as a character? and argues that there may be compilers with integer types that would be rather than an alias for the basic C ++ types. Therefore, in this case, overloads for all main cases may not accept it. On the other hand, I cannot provide overloading for int8_t, since on many platforms it is just an alias and will receive an error to override the existing overloading.

+4
source share
4 answers

, , . , C ++ , " ":

.

, ...

.

C stdint.h. , :

, .

, , : (, SFINAE ) , std::intmax_t. , intmax_t - :

,

, , " " . , std::intmax_t , .

+10

int8_t int ( intmax_t, , . (I , int, [ ], ++ , )

, int8_t signed char .

+1

, . , , , , .

, - , , typeid , , .

#include <cstdint>
#include <iostream>
#include <iomanip>
#include <typeinfo>

int main() {
    std::cout << std::left;
    std::cout << std::setw(10) << "int8_t: "   << typeid(int8_t).name()   << '\n'
              << std::setw(10) << "int16_t: "  << typeid(int16_t).name()  << '\n'
              << std::setw(10) << "int32_t: "  << typeid(int32_t).name()  << '\n'
              << std::setw(10) << "int64_t: "  << typeid(int64_t).name()  << '\n'
              << std::setw(10) << "uint8_t: "  << typeid(uint8_t).name()  << '\n'
              << std::setw(10) << "uint16_t: " << typeid(uint16_t).name() << '\n'
              << std::setw(10) << "uint32_t: " << typeid(uint32_t).name() << '\n'
              << std::setw(10) << "uint64_t: " << typeid(uint64_t).name() << '\n'
              << std::endl;

    std::cout << std::setw(20) << "char: "               << typeid(char).name()               << '\n'
              << std::setw(20) << "signed char: "        << typeid(signed char).name()        << '\n'
              << std::setw(20) << "unsigned char: "      << typeid(unsigned char).name()      << '\n'
              << std::setw(20) << "signed short: "       << typeid(signed short).name()       << '\n'
              << std::setw(20) << "unsigned short: "     << typeid(unsigned short).name()     << '\n'
              << std::setw(20) << "signed int: "         << typeid(signed int).name()         << '\n'
              << std::setw(20) << "unsigned int: "       << typeid(unsigned int).name()       << '\n'
              << std::setw(20) << "signed long: "        << typeid(signed long).name()        << '\n'
              << std::setw(20) << "unsigned long: "      << typeid(unsigned long).name()      << '\n'
              << std::setw(20) << "signed long long: "   << typeid(signed long long).name()   << '\n'
              << std::setw(20) << "unsigned long long: " << typeid(unsigned long long).name() << '\n'
              << std::endl;
}

:

// MSVC 2015 (x86 & x64):
int8_t:   signed char
int16_t:  short
int32_t:  int
int64_t:  __int64
uint8_t:  unsigned char
uint16_t: unsigned short
uint32_t: unsigned int
uint64_t: unsigned __int64

char:               char
signed char:        signed char
unsigned char:      unsigned char
signed short:       short
unsigned short:     unsigned short
signed int:         int
unsigned int:       unsigned int
signed long:        long
unsigned long:      unsigned long
signed long long:   __int64
unsigned long long: unsigned __int64

// Clang & GCC (x64):
int8_t:   a
int16_t:  s
int32_t:  i
int64_t:  l
uint8_t:  h
uint16_t: t
uint32_t: j
uint64_t: m

char:               c
signed char:        a
unsigned char:      h
signed short:       s
unsigned short:     t
signed int:         i
unsigned int:       j
signed long:        l
unsigned long:      m
signed long long:   x
unsigned long long: y

:

  • MSVC ( x86, x64 Windows, ILP32 LLP64 ): , ; , 64- __int64 ( long long , ) long long
  • Clang GCC ( x64 * nix): , , :
    • 8- char.
    • 16- short.
    • 32- int.
    • 64- long.

, :

  • signed char int8_t.
  • unsigned char uint8_t.
  • signed short int16_t.
  • unsigned short uint16_t.
  • ...
  • [ , - LLP64 * nix LP64 Windows, int64_t uint64_t .]

, , , , , .


XY. , , , , , , , .

, , ; - , .

void func(          char);
void func(  signed  char);
void func(unsigned  char);
void func(         short);
void func(unsigned short);
// ...

#ifdef PLATFORM_WHERE_INT8_T_ISNT_SIGNED_CHAR
    void func( int8_t);
    void func(uint8_t);
#endif

#ifdef PLATFORM_WHERE_INT16_T_ISNT_SIGNED_SHORT
    void func( int16_t);
    void func(uint16_t);
#endif

// ...

​​, , , , . , ( ).

+1

, int8_t - ?

No, not for int8_t. Even if int8_tit is not an alias of one of the standard integer types, it is still converted to other integer types, and progressing to is intunambiguously preferable. Thus, an extended call int8_twould resolve one of the overloads.

However, for larger types, this is still a problem.

0
source

Source: https://habr.com/ru/post/1666277/


All Articles