首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在C++中显示所有基本类型数据大小的程序

在C++中显示所有基本类型数据大小的程序
EN

Stack Overflow用户
提问于 2016-12-12 04:25:35
回答 1查看 349关注 0票数 0

当我使用特定的数据类型时,我通常需要知道它在程序中所占的大小。最近,我想到了一个通用的解决方案,可以为C++语言中的所有数据类型处理这个问题,包括类型别名和用户定义的数据类型。

当我开始实现时,我意识到编写一个适用于所有平台的可移植程序并不容易,因为C++中的数据类型实际上是编译器、体系结构和操作特定的实体。

它在很大程度上是有效的,但有一些边缘情况我不能处理,还有几个点我不确定。

项目简介:

该程序使用模板专门化来区分基本数据类型。操作是通过模板专门化的编译时和决策机制工作。这样做的问题是,如果将两个类型推导为相同的类型(包括类型别名),则恰好会出现编译器错误。

一个简短的例子是:

"short“或"short int”或"signed short“可能都等同于编译器所认为的"short int”(当然,这可以是编译器特定的特征)。如果"short“和"short int”都被提供给程序,模板专门化机制会报告已经定义了一个。

所以问题是:

例如,我如何确定"short“、"short int”或"signed short“类型是否会被推导为相同的类型?有没有办法在编译时检查它?

类型别名的情况也是如此,因为模板专门化是通过它们的原始类型进行的。同样,如果同时提供了"short int“和"std::size_t”,并且"std::size_t“恰好被系统定义为"short int”,程序将不会编译,因为编译器会抱怨已经有一个专门的模板。

我使用下面的link来确保哪些类型彼此等价,但我怀疑实现规则可能并不是所有编译器都遵循的。

我得到的输出。

代码语言:javascript
复制
bool                    : 1 bytes | 8 bits
char                    : 1 bytes | 8 bits
signed char             : 1 bytes | 8 bits
unsigned char           : 1 bytes | 8 bits
wchar_t                 : 4 bytes | 32 bits
char16_t                : 2 bytes | 16 bits
char32_t                : 4 bytes | 32 bits
short int               : 2 bytes | 16 bits
unsigned short int      : 2 bytes | 16 bits
int                     : 4 bytes | 32 bits
unsigned int            : 4 bytes | 32 bits
long int                : 8 bytes | 64 bits
unsigned long int       : 8 bytes | 64 bits
long long int           : 8 bytes | 64 bits
unsigned long long int  : 8 bytes | 64 bits
float                   : 4 bytes | 32 bits
double                  : 8 bytes | 64 bits
long double             : 16 bytes | 128 bits
nullptr_t               : 8 bytes | 64 bits
Example                 : 168 bytes | 1344 bits
NULL macro is of integral type.

这是我在概念上所需要的:

代码语言:javascript
复制
bool                    : 1 bytes | 8 bits
char                    : 1 bytes | 8 bits
signed char             : 1 bytes | 8 bits
unsigned char           : 1 bytes | 8 bits
wchar_t                 : 4 bytes | 32 bits
char16_t                : 2 bytes | 16 bits
char32_t                : 4 bytes | 32 bits
short int               : 2 bytes | 16 bits
// -----------WHAT I NEED CONCEPTUALLY----------------
short                   : short is same as short int             //This would be a compile-time error normally.
signed short int        : signed short int is same as short int  //This would also be a compiler time error.
std::size_t             : std::size_t is of short int type.      //Since "short int" is already defined, this is compile-time error as well.
//-----------------------------------------------------
unsigned short int      : 2 bytes | 16 bits
int                     : 4 bytes | 32 bits
unsigned int            : 4 bytes | 32 bits
long int                : 8 bytes | 64 bits
unsigned long int       : 8 bytes | 64 bits
long long int           : 8 bytes | 64 bits
unsigned long long int  : 8 bytes | 64 bits
float                   : 4 bytes | 32 bits
double                  : 8 bytes | 64 bits
long double             : 16 bytes | 128 bits
nullptr_t               : 8 bytes | 64 bits
Example                 : 168 bytes | 1344 bits
NULL macro is of integral type.

下面是代码。

代码语言:javascript
复制
#ifndef TYPE_INFO_CPP
#define TYPE_INFO_CPP

#include <iostream>
#include <iomanip>
#include <type_traits>

/*
    Just call:
        SYS_CHECK();
    In your main function
*/


//Types given into the template function as template parameters via macro
#define TYPES   bool,                       \
                char,                       \
                signed char,                \
                unsigned char,              \
                wchar_t,                    \
                char16_t,                   \
                char32_t,                   \
                short int,                  \
                unsigned short int,         \
                int,                        \
                unsigned int,               \
                long int,                   \
                unsigned long int,          \
                long long int,              \
                unsigned long long int,     \
                float,                      \
                double,                     \
                long double,                \
                std::nullptr_t,             \
                Example
//              std::size_t,                \
//              std::string::size_type

//Dummy Struct Declaration to enable Template Specialization
template <typename T>
struct TypeTraits;

//Template Specialization via macro
//Template Specialization is used to distinguish different types
#define REGISTER_TYPE(X)                                \
    template <>                                         \
    struct TypeTraits <X> {                             \
        static const char * name;                       \
    };                                                  \
    const char * TypeTraits<X>::name = #X;

//To get rid of std:: prefix during console output
#define INTRODUCE_NULLPTR_T()   \
    using std::nullptr_t;

//Example User-Defined Type Body
struct Example {
    char arr1[100];
    int a;
    double b;
    char arr2[50];
};

//These macros are short-hand for declaring specialized templates of the dummy template declared above
REGISTER_TYPE(bool)
REGISTER_TYPE(char)
REGISTER_TYPE(signed char)
REGISTER_TYPE(unsigned char)
REGISTER_TYPE(wchar_t)
REGISTER_TYPE(char16_t)
REGISTER_TYPE(char32_t)
REGISTER_TYPE(short int)
REGISTER_TYPE(unsigned short int)
REGISTER_TYPE(int)
REGISTER_TYPE(unsigned int)
REGISTER_TYPE(long int)
REGISTER_TYPE(unsigned long int)
REGISTER_TYPE(long long int)
REGISTER_TYPE(unsigned long long int)
REGISTER_TYPE(float)
REGISTER_TYPE(double)
REGISTER_TYPE(long double)

//Example User-Defined Type
REGISTER_TYPE(Example)

INTRODUCE_NULLPTR_T()
REGISTER_TYPE(nullptr_t)

template <bool T = std::is_integral<decltype(NULL)>::value, 
          bool U = std::is_pointer<decltype(NULL)>::value,
          bool Y = std::is_scalar<decltype(NULL)>::value>
void is_NULL_integral() {
    std::cout << "NULL macro is of ";
    if (T) {
        std::cout << "integral";
    }
    else if (U) {
        std::cout << "pointer";
    }
    else if(Y) {
        std::cout << "nulltpr_t";
    }
    else {
        std::cout << "neither pointer nor integral or scalar";
    }
    std::cout << " type." << std::endl;
}

template <typename T, short int byte = 8>
void convert_byte_to_bit() {
    std::cout << " | ";
    std::cout << byte * sizeof(T) << " bits" << std::endl;
}

template <typename T>
void _display_helper() {
    std::cout << std::left << std::setw(23) << TypeTraits<T>::name << " : " 
        << sizeof(T) << " bytes" << std::left;
    convert_byte_to_bit<T>();
}

template <typename T>
void display_default_size() {
    _display_helper<T>();
}

template <typename T, typename U, typename ... Args>
void display_default_size() {
    _display_helper<T>();
    display_default_size<U, Args...>();
}

void SYS_CHECK() {
    display_default_size<TYPES>();
    std::cout << std::endl;
    is_NULL_integral();
}
#endif
EN

回答 1

Stack Overflow用户

发布于 2016-12-12 04:33:19

例如,我如何确定"short“、"short int”或"signed short“类型是否会被推导为相同的类型?有没有办法在编译时检查它?

您已将您的问题标记为C++11,因此...这是一项针对类型特征的工作;std::is_same

它在编译时工作。

举例说明

代码语言:javascript
复制
#include <type_traits>
#include <iostream>

int main()
 {
   constexpr bool b1 { std::is_same<short, short int>::value };
   constexpr bool b2 { std::is_same<short, signed short int>::value };
   constexpr bool b3 { std::is_same<short, unsigned short int>::value };

   std::cout << b1 << std::endl;  // print 1
   std::cout << b2 << std::endl;  // print 1
   std::cout << b3 << std::endl;  // print 0
 }

En passant:shortshort intsigned short int的别名

编辑--

操作员问

在C++11标准中有没有提到" short“和"short int”确实是"signed short int“的别名?有没有什么资源我也可以用来查找其他基础类型?

我不知道标准在哪里提到了它,但这是从旧的C语言开始的一个基本方面;你已经链接了一个很棒的(IMHO)资源;在页面中你可以链接(this page)你可以读到

  • “如果使用下面列出的任何修饰符,则可以省略关键字int”,
  • signed“是默认值,如果省略”
  • “,并且”对于所有类型说明符,允许任何顺序“。

因此(举个例子) signed short intshort signed intshort int signedsigned int shortint signed shortint short signedsigned shortshort signedshort是同一类型的别名。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41090782

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档