c++新特性实验(2)类型特性
1. 基本类型
1.1 增加
long long long long int signed long long signed long long int unsigned long long unsigned long long int |
至少 64 位的宽度 | C++11 |
char8_t | UTF-8 字符类型 | C++20 |
char16_t | UTF-16 字符类型 | C++11 |
char32_t | UTF-32 字符类型 | C++11 |
1.2 修改char的符号(C++14)
char 的符号取决于编译器和目标平台:
- ARM 和 PowerPC 的默认设置常为无符号,
- 而 x86 与 x64 的默认设置常为有符号。
1.3 示例
#include <cstdlib>
#include <cstdio> int
main(int argc,char *argv[]){ unsigned long long ull = ;
unsigned long long int ulli = ;
signed long long sll = ;
signed long long int slli = ; long long ll = ;
long long int lli = ; printf("unsigend long long = %ld \n",sizeof ++ull);
printf("ull = %ld \n",ull); char16_t ch16 = u'\u5b89';
char32_t ch32 = U'\u5353';
printf("ch16 = %c ,char32 = %c \n",ch16,ch32); return ;
}
2.固定字节数的整形类型(C++11 起)
定义于头文件 <cstdint>
int8_t,int16_t,int32_t,int64_t | 分别为宽度恰为 8、16、32 和 64 位的有符号整数类型 |
int_fast8_t,int_fast16_t,int_fast32_t,int_fast64_t, | 分别为宽度至少有 8、16、32 和 64 位的最快的有符号整数类型 |
int_least8_t,int_least16_t,int_least32_t,int_least64_t | 分别为宽度至少有 8、16、32 和 64 位的最小的有符号整数类型 |
intmax_t,uintmax_t | 最大宽度的有符号整数类型和无符号整数类型 |
intptr_t,uintptr_t | 足以保存指针的有符号整数类型和无符号整数类型 |
uint8_t,uint16_t,uint32_t,uint64_t | 宽度恰为 8、16、32 和 64 位的无符号整数类型. |
uint_fast8_t,uint_fast16_t,uint_fast32_t,uint_fast64_t | 分别为宽度至少有 8、16、32 和 64 位的最快无符号整数类型 |
uint_least8_t,uint_least16_t,uint_least32_t,uint_least64_t | 分别为宽度至少有 8、16、32 和 64 位的最小无符号整数类型 |
3.基本类型宏(C++11 起)
定义于头文件 <cstddef>
nullptr_t,nullptr | 空指针字面量. | C++11 |
max_align_t | 具有不小于任何基础类型的内存对齐需求的平凡类型 | C++11 |
byte
|
字节类型 ,它在std::下。 | C++17 |
__bool_true_false_are_defined
|
C 兼容用宏常量,展开成整数常量1 | C++11 |
__alignas_is_defined
|
C 兼容用宏常量,展开成整数常量 1 | C++11 |
4.类型特性(C++11 起)
类型特性用以查询或修改类型的属性,通常在模板中使用.
定义于头文件 <type_traits>
4.1 基础类型类别
is_void
|
检查类型是否为 void | C++11 |
is_null_pointer
|
检查类型是否为 std::nullptr_t | C++14 |
is_integral
|
检查类型是否为整型 | C++11 |
is_floating_point
|
检查类型是否是浮点类型 | C++11 |
is_array
|
检查类型是否是数组类型 | C++11 |
is_enum
|
检查类型是否是枚举类型 | C++11 |
is_union
|
检查类型是否为联合体类型 | C++11 |
is_class
|
检查类型是否非联合类类型 | C++11 |
is_function
|
检查是否为函数类型 | C++11 |
is_pointer
|
检查类型是否为指针类型 | C++11 |
is_lvalue_reference
|
检查类型是否为左值引用 | C++11 |
is_rvalue_reference
|
检查类型是否为右值引用 | C++11 |
is_member_object_pointer
|
检查类型是否为指向非静态成员对象的指针 | C++11 |
is_member_function_pointer
|
检查类型是否为指向非静态成员函数的指针 | C++11 |
4.2 复合类型类别
is_fundamental
|
检查是否是基础类型 | C++11 |
is_arithmetic
|
检查类型是否为算术类型 | C++11 |
is_scalar
|
检查类型是否为标量类型 | C++11 |
is_object
|
检查是否是对象类型 | C++11 |
is_compound
|
检查是否为复合类型 | C++11 |
is_reference
|
检查类型是否为左值引用或右值引用 | C++11 |
is_member_pointer
|
检查类型是否为指向非静态成员函数或对象的指针类型 | C++11 |
4.3 类型属性、类型关系、受支持操作
参看:http://en.cppreference.com/w/cpp/types
4.4示例
#include <type_traits>
#include <cstddef>
#include <cstdlib>
#include <cstdio>
#include <cstdint> using namespace std; class student{
public:
byte age;
public:
student(byte _age):age(_age){ }
student(){
student((byte));
}
}; template<typename T>
void
fun(T const &t){
printf("\n-------==============------------=====-----------\n");
printf("t = %d\n",t);
printf("t.is_void = %d\n" ,is_void<T>::value );
printf("t.is_integral = %d\n" ,is_integral<T>::value );
printf("t.is_null_pointer = %d\n" ,is_null_pointer<T>::value );
printf("t.is_pointer = %d\n" ,is_pointer<T>::value );
printf("t.is_class = %d\n" ,is_class<T>::value );
printf("t.is_lv_reference = %d\n" ,is_lvalue_reference<T>::value);
printf("t.is_array = %d\n" ,is_array<T>::value);
if(is_array<T>::value){
printf("t.rank = %ld\n" ,rank<T>::value);
}
} //template<typename U>
void fun(nullptr_t null){
} template<typename F, typename A>
void
funfwd(F _fun, A _arg)
{
_fun(_arg);
} void
g(int* i){
printf("function g called \n");
} int
main(int argc,char *argv[]){
byte age = (byte);
int8_t int8[] = {,,,};
int64_t int64 = , &refInt64 = int64;
int_fast64_t *pFastInt64 = &int64;
nullptr_t nullp; byte *pb = &age;
student s = {age};
printf("s.age = %d\n",s.age); fun();
fun<student>(s);
//fun<void>(1);
fun(pFastInt64);
fun(int8);
fun(refInt64);
fun(nullp); g(NULL); // ok
g(); // ok
funfwd(g, nullptr); // ok
//funfwd(g, NULL); // error:NULL是个宏,值是0,这里展开后不存在函数 g(int) return ;
}
4.5类型修改
remove_cv
|
从给定类型移除 const 或/与 volatile 限定符 | C++11 |
remove_const
|
||
remove_volatile
|
||
add_cv
|
添加 const 或/与 volatile 限定符到给定类型 |
C++11 |
add_const
|
||
add_volatile
|
||
remove_reference
|
从给定类型移除或者添加引用 | C++11 |
add_lvalue_reference
add_rvalue_reference
|
||
remove_pointer | 移除给定类型的一级指针 | C++11 |
add_pointer | 对给定类型添加一级指针 | C++11 |
示例
#include <cstdio>
#include <cstdlib>
#include <type_traits> using namespace std; template<typename T>
void
fun(const T &t){
printf("t is const = %d\n",is_const<T>::value); typedef remove_cv<const int>::type type1; } int
main(int argc,char *argv[]){ const int a = ;
fun(); typedef remove_cv<const int>::type type1;
typedef remove_cv<volatile int>::type type2;
typedef remove_cv<const volatile int>::type type3;
typedef remove_cv<const volatile int*>::type type4;
typedef remove_cv<int * const volatile>::type type5; printf("test1 : %s \n" ,(is_same<int, type1>::value ? "passed" : "failed" ));
printf("test2 : %s \n" ,(is_same<int, type2>::value ? "passed" : "failed" ));
printf("test3 : %s \n" ,(is_same<int, type2>::value ? "passed" : "failed" ));
printf("test4 : %s \n" ,(is_same<const volatile int*, type4>::value ? "passed" : "failed" ));
printf("test5 : %s \n" ,(is_same<int*, type5>::value ? "passed" : "failed" )); return ;
}
5.字面类型(C++11 起)
5.1 哪些类型是字面类型
- 标量类型;
- 引用类型;
- 字面类型的数组;
- 可为 cv 限定的 void (从而 constexpr 函数能返回 void )(C++14 起);
- 可有 cv 限定的类类型,并拥有下列全部约束:
-
- 拥有析构函数,
- 满足以下条件之一
- 聚合类型
- 或拥有至少一个 constexpr 构造函数(可为模板)且非复制或移动构造函数
- 或为闭包类型 (C++17 起)
- 对于联合体,至少有一个非静态数据成员是非 volatile 字面类型,
- 对于非联合体,所有非静态数据成员和基类是非 volatile 字面类型。
- 所有非静态数据成员和基类是非 volatile 字面类型。
5.2 示例
#include <stdexcept>
#include <cstdlib>
#include <cstdio> using namespace std; class conststr{
public:
const char* p;
size_t sz;
template<size_t N>
constexpr conststr(const char(&a)[N]) : p(a), sz(N - ) {} constexpr char operator[](size_t n) const {
return n < sz ? p[n] : throw out_of_range("");
}
constexpr size_t size() const { return sz; }
}; constexpr size_t countlower(conststr s, size_t n = ,size_t c = ){
return n == s.size() ? c : s[n] >= 'a' && s[n] <= 'z' ? countlower(s, n + , c + ) : countlower(s, n + , c);
} // 要求编译时常量的输出函数,为测试用
template<int n>
struct constN{
constN() {
printf("n = %d \n",n);
}
}; int
main(int argc,char *argv[]){
constN<countlower("Hello, world!")>(); // 隐式转换成 conststr
return ;
}
c++新特性实验(2)类型特性的更多相关文章
- C# 9.0 新特性预览 - 类型推导的 new
C# 9.0 新特性预览 - 类型推导的 new 前言 随着 .NET 5 发布日期的日益临近,其对应的 C# 新版本已确定为 C# 9.0,其中新增加的特性(或语法糖)也已基本锁定,本系列文章将向大 ...
- c++新特性实验(4)声明与定义:右值引用(C++11)
1.作用 c++11以前,临时对象.字面常量一般情况下不可以再次访问,也不可以修改.右值引用可以解决这个问题. 1.1 实验A #include <iostream> using name ...
- JS面向对象特性和值类型与复合类型
JS面向对象之特性已经值类型与复合类型 一些属性 空对象 空对象也是对象, 只是有存变量的变量名, 没有对象属性 var o ={}; 参数传递 值类型: 函数内外两个变量, 两个数据, 都不相同 ...
- 代码走查25条疑问 C# 跳转新的标签页 C#线程处理 .Net 特性 attribute 学习 ----自定义特性 看懂 ,学会 .NET 事件的正确姿势-简单版
代码走查25条疑问 代码走查(Code Review) 是一个开发人员与架构师集中讨论代码的过程.通过代码走查可以提高代码的 质量,同时减少Bug出现的几率.但是在小公司中并没有代码走查的过程在这 ...
- spring事务传播特性实验(2):PROPAGATION_REQUIRED实验结果与分析
本文延续上一文章(spring事务传播特性实验(1):数据准备),在已经准备好环境的情况下,做如下的实验,以验证spring传播特性,加深对spring传播特性的理解. 本次主要验证PROPAGATI ...
- swift 声明特性 类型特性
原文地址:http://www.cocoachina.com/newbie/basic/2014/0612/8801.html 特性提供了关于声明和类型的很多其它信息.在Swift中有两类特性,用于修 ...
- TypeScript01 编译环境的搭建、字符串特性、类型特性
知识准备:JavaScript满足ES5前端规范.TypeScript满足ES6前端规范 1 TypeScript开发环境 TypeScript代码不能直接被浏览器识别,必须先转换成JS代码:通常是利 ...
- Git使用总结 Asp.net生命周期与Http协议 托管代码与非托管代码的区别 通过IEnumerable接口遍历数据 依赖注入与控制反转 C#多线程——优先级 AutoFac容器初步 C#特性详解 C#特性详解 WPF 可触摸移动的ScrollViewer控件 .NET(C#)能开发出什么样的APP?盘点那些通过Smobiler开发的移动应用
一,原理 首先,我们要明白Git是什么,它是一个管理工具或软件,用来管理什么的呢?当然是在软件开发过程中管理软件或者文件的不同版本的工具,一些作家也可以用这个管理自己创作的文本文件,由Linus开发的 ...
- 201671030108后新莉+实验十四 团队项目评审&课程学习总结
项目 内容 这个作业属于哪个课程 代老师博客主页 这个作业的要求在哪里 实验十四 团队项目评审&课程学习总结 作业学习目标 (1)掌握软件项目评审会流程:(2)温故知新自己的所得:(3)反思总 ...
随机推荐
- 使用CEfSharp之旅(6)拦截网络请求 截取response返回
原文:使用CEfSharp之旅(6)拦截网络请求 截取response返回 版权声明:本文为博主原创文章,未经博主允许不得转载.可点击关注博主 ,不明白的进群191065815 我的群里问 https ...
- ajax无刷新上传
我们在使用上传控件的时候,会遇到刷新的问题,最近使用ajax做的上传,觉得效果还是很不错. 首先,我们需要在页面上放上上传控件:需要注意的是,我们必须放在form里面,实现表单上传. <for ...
- eclipse-帮助文档
Eclipse开发环境配置 1. java环境 安装 本系统使用java6开发,老师使用1.6.0 _45版本开发,如下图所示: “开发工具”目录提供了1.6.0 _45版本32位和6 ...
- 【主席树】 [CQOI2015]任务查询系统
模板题... 差分,然后用主席树维护时间点上的优先值和就好了 就是细节烦... #include<bits/stdc++.h> #define int long long #define ...
- DMZ在虚拟化环境中的部署
常见的方法有三种: 1.分别部署 2.部分虚拟化 3.全部虚拟化 传统DMZ部署结构: 分别部署: 想要保持DMZ区域物理隔离采用这种方法,每个区域分别部署进入不同的服务器集群,区域之间的连接采用物理 ...
- splay区间翻转
原题P3391 [模板]文艺平衡树(Splay) 题目背景 这是一道经典的Splay模板题——文艺平衡树. 题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: ...
- 为什么要使用Vue.$set(target,key,value)
vue中不能检测到数组和对象的两种变化: 1.数组长度的变化 vm.arr.length = 4 2,数组通过索引值修改内容 vm.arr[1] = 'aa' Vue.$set(target,key, ...
- mui.fire()用法
作用: mui.fire() 可以触发目标窗口的自定义事件 mui.fire( 目标窗口的webview , '自定义事件名' ,{参数列表}:) 目标窗口监听这个自定义事件 window.addEv ...
- ES6 学习笔记(基础)
书链接:http://es6.ruanyifeng.com/ #.let let 不存在“变量提升” 暂时性死区(即:let 所定义的变量在局部作用域中不受外界影响) var tmp = 123; i ...
- 利用refind实现UEFI多系统引导
使用DiskGenius Pro给ESP分区指定盘符,目的是为了让ESP分区在硬盘上可见 使用BOOTICE工具中的UEFI选项卡中的功能调整引导顺序 修改启动序列-->EFI NetWork- ...