2016-12-11 24 views
0

當我使用特定的數據類型時,通常需要知道它在程序中佔用的大小。最近我想到了通用解決方案,它將處理C++語言中所有數據類型的這個問題,包括類型別名和用戶定義的數據類型。當我開始實現時,我意識到爲所有平臺編寫可移植程序並不容易,因爲C++中的數據類型實際上是編譯器,體系結構和操作特定的實體。程序在C++中顯示所有基本類型的數據大小

它主要是工作,但有一些邊緣案例我不能處理和夫妻關係,我不知道。

方案的簡要說明:

該程序使用模板專門 基本數據類型之間進行區分。操作是編譯時和決策機制 通過模板專業化工作。問題是如果兩種類型被推斷爲包括類型別名的相同類型,那麼碰巧存在編譯器錯誤。

簡單例子是:

「短」或「短整型」或「符號的短」可以是所有等同於「短整型」所感知由編譯器(當然這可以確實編譯器特定的特徵)。如果程序都提供了「short」和「short int」,模板專門化機制會抱怨已經定義了一個。

所以,問題是:

我怎樣才能確保,例如,無論是類型「短」,「短整型」或「符號短」會被推斷爲同一類型或不?有沒有辦法在編譯時檢查?

類型別名的情況也是如此,因爲模板特化是通過它們的原始類型發生的。同樣,如果同時提供「short int」和「std :: size_t」,並且如果系統定義「std :: size_t」爲「short int」,程序將不編譯,因爲編譯器會抱怨存在已經有一個專門的模板。

我已經使用以下link來確定哪些類型相互等價,但我懷疑實現規則可能不會被所有編譯器遵循。

我得到的輸出。

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. 

這在概念上我所需要的:

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. 

這裏是代碼。

#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 
+0

你有沒有試過諮詢'限制'頭文件? –

+0

我應該在那裏找到什麼信息? – ugar

回答

1

我怎樣才能確保,例如,無論是類型「短」,「短整型」或「符號短」會被推斷爲同一類型或不?有沒有辦法在編譯時檢查?

你已經標記了你的問題C++ 11 so ...這是一個類型特徵的工作; std::is_same

它工作的編譯時間。

例如

#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 
} 

順便:shortshort int是別名signed short int

---編輯---

的OP問

是在C++ 11標準中有任何提及其中聲明「short」和「short int」確實是「signed short int」的別名?是否有任何資源可用於查找其他基本類型?

我不知道標準提到它在哪裏,但是從舊C開始的一個基本方面;你已經鏈接了一個美好的(恕我直言)資源;在你的頁面鏈接(this page),你可以閱讀

  • ,「如果下面列出的任何修飾都使用關鍵字INT可以省略」,
  • signed「是默認的,如果省略」
  • 和「與所有類型說明符,允許任何命令」。

所以(由例如)signed short intshort signed intshort int signedsigned int shortint signed shortint short signedsigned shortshort signedshort和用於相同類型別名。

+0

在C++ 11標準中有沒有提到「short」和「short int」確實是「signed short int」的別名?是否有任何資源可用於查找其他基本類型? – ugar

+0

@ugarbd - 答案改進;希望這可以幫助。 – max66

相關問題