当我使用特定的数据类型时,我通常需要知道它在程序中所占的大小。最近,我想到了一个通用的解决方案,可以为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来确保哪些类型彼此等价,但我怀疑实现规则可能并不是所有编译器都遵循的。
我得到的输出。
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发布于 2016-12-12 04:33:19
例如,我如何确定"short“、"short int”或"signed short“类型是否会被推导为相同的类型?有没有办法在编译时检查它?
您已将您的问题标记为C++11,因此...这是一项针对类型特征的工作;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
}En passant:short和short int是signed short int的别名
编辑--
操作员问
在C++11标准中有没有提到" short“和"short int”确实是"signed short int“的别名?有没有什么资源我也可以用来查找其他基础类型?
我不知道标准在哪里提到了它,但这是从旧的C语言开始的一个基本方面;你已经链接了一个很棒的(IMHO)资源;在页面中你可以链接(this page)你可以读到
signed“是默认值,如果省略”因此(举个例子) signed short int、short signed int、short int signed、signed int short、int signed short、int short signed、signed short、short signed和short是同一类型的别名。
https://stackoverflow.com/questions/41090782
复制相似问题