static_assert(sizeof(int)==2, "no support 16");
//如:
typedef std::vector<std::vector<bool> >Flags;
//在早期必须分开 因为优先度 不同 会别解析位 右移符号
//如果类未声明,要使其为友元,那么需要使用 class 或者 struct 来指明其类
//如:
class B
{
friend class A;
};
class A
{
};
//是被允许的
/函数 printf 使用% lld 来支持输出
//(在vc6 支持不好)
//头文件 #include '
//比如 is_void is_integral is_array is_enum
//is_void is_null_pointer is_funciton等等 ..
//如:
struct trivial
{
int val;
};
std::cout << std::is_void<trivial>::value << endl;
std::cout<< std::is_void<void>::value << std::endl;
//示例:int func(); auto& x = func(); const auto& x = func(); 这样都会报错
//不能在临时变量上面使用引用
//允许多个变量: int i;auto a=1,*b
//禁止自己初始化自己 auto j=&j
//允许初始化 auto x(1)
//允许 new 比如 new auto(1.0)
//允许 auto*x = new auto(1)
//改变 auto 不再是存储类型的一种了(老版里面它是一种存储类型,其他的还包括 register、
//mutable、static、extern)
//允许一个构造函数使用另外一个构造进行构造
// 比如:class Foo{
// public:
// Foo(char x,int y) {}
// Foo(int y) :Foo(‘a’,y) {}
//}
允许在不同的位置声明和使用模板
// 示例:extern template class vector
// 主要是避免同一种类型的模板被反复实现
// 连累编译器和链接器最后要去重,浪费大量时间
期待函数能够在编译器就得出返回值
//是给模板用的
//这个和 const 不同,const 表示函数返回的类型是 const 属性的
//简单点说 const 更多的是只读的含义,而 constexpr 才是常量
using vec = vector<T, Alloc<T>>;
关键字
char16_t、char32_t
允许 16bit 和 32bit 的字符,
为多种编码而设置 UTF-8 UTF-16 UTF-3
可以声明类/结构体/联合体/无属性类/变量(不能是形参)
如:
按照浮点对齐
struct alignas(float) struct_float {
float a;
};
按照256个字节对齐
struct alignas(256) struct_256 {
int aa;
int b;
};
按照64字节对齐
alignas(64) char lien555[128];
获得一个类型的长度
允许使用默认的函数或者删除函数
这样就开源使得子类自由保留或者去除父类函数
如:
class A
{
A() = default;
A& operator==(A& a) = delete;
};
解决传统枚举的几个问题
1 隐式转换为整数
2 枚举类型的大小会依据实现出现变化
这样枚举类型的变量其 size 无法确定
3 同名枚举成员会产生重名错误
4 解决上面问题的适合,避免扩展不兼容问题
要求实参和形参类型完全一致,不提供隐式转换
包括 const volatile
也包括&&右值引用 &引
支持更多的字符串类型
比如 u8”” u”” U”” L”” “”
允许在名称空间内部声明和使用名称空间
Trailing function return types
Unrestricted unio
template<typename... Types>
template<typename... Types>
Tuple<Types...> make_tuple(Types&&... args)
{
return tuple<Types...>(args..);//圆组
}
全称 Substitution Failure Is Not An Error 即 替换失败不是错
class A
{
};
template<typename T>
class is_tclass
{
typedef char yes[1];
typedef char no[2];
template<typename C> static yes& test(int C::*); // selected if C is a class type
template<typename C> static no& test(...); // selected otherwise
public:
static bool const value = sizeof(test<T>(0)) == sizeof(yes);
//编译 但是没有实现
//可以通过 value 来判断类型 T 是类还是其他
};
int main()
{
cout << is_tclass<A>::value << endl;
cout << is_tclass<int>::value << endl;
}
:::为什么
模拟 1 当时类 A
T==A
test<A>(0) 在sizeof里面 不会被调用 只需要返回值
test第一个是一个成员函数指针 0 是 NULL
A 是有成员函数指针的
所以返回yes
模拟2 int
int是 不存在int::* 这个匹配第二个
返回 no
动态并发初始化和析构 线程存储和静态存储进
class A
{
public:
int a;
int b;
int c;
};
int main()
{
A a = { 10,10,10, };
}
非静态数据成员初始化 允许对非静态成员进行
其他属性修饰还包括[[noreturn]]
[[carries_dependency]]
[[deprecated]]或者[[deprecated(“原因")]][[fallthrough]]
[[nodiscard]]或者[[nodiscard("原因")]][[likely]][[unlikely]]
[[no_unique_address]]
[[optimize_for_synchronized]]
允许用户自定义数据标识
比如:
#include
#include
#include
using namespace std::chrono_literals;//标准库的预定义文字量:用法:1000msusing Ms = std::chrono::milliseconds;//类型别名
auto operator""_ms(unsigned long long value) { return Ms(value);}//自定义的文字量,用100o_ms
int main() {
std:this_thread::sleep_for( std:chrono::millisecond(1000));std::this_thread:sleep_for( Ms(3000) );
std::this_thread:sleep_for( 300o_ms );std::this_thread:sleep_for( 3000ms );
}
//=========================
auto operator "" t(unsigned long long value)//自定义数据标识
{
return 1000 * value;
}
auto operator "" utf8(const char* s)
{
//转码函数
return string(s)+"utf8";
}
int main()
{
int weight = 10t;
cout << weight << endl;
cout << 1000utf8 << endl;
}
匿名函数对象
[捕获列表](参数列表)修饰符 -> 返回值 {函数体}
捕获为空,表示不捕获任何值,表达式内外的变量不能互访
&,表示用引用的方式捕获所有变量,表达式可以读写外部变量
=,表示用值的方式捕获所有变量,表达式可以用只读的方式访问外部变量
this,表示捕获 this 指针,这样 lambda 就可以通过 t
*this,表示以值的形式使用成员
变量名称,表示以值的形式捕获指定变量,表达式可以读取该变量值
&变量名称,表示以引用的形式捕获指定变量,表达式可以读写该变量值
捕获方式可以在不冲突的情况下任意组合
例如
[&,var1,var2]除了 var1 和 var2 以值捕获,其他变量以引用捕获
[=,this,&var]var 以引用捕获,其他以值捕获,同时捕获 this指针
多用于函数做为参数传递的情况
比如 std 的 for_each
捕获的变量不能重复或者冲突
[i,i]、[this,*this]是不被允许的
Lambda 可以嵌套
例如:
auto f(){
return [&]{
return [=]{
return
}
}
}
注意,lambda 默认时 const 修饰的的函数,如果注明是 mutable,才能修改本地变量
语法糖,可以解决一些回调函数的问题
```cpp
int main()
{
UINT nMsg = 10;
auto func = [&](WPARAM w, LPARAM l)-> LRESULT {};
map<UINT, decltype(func)>msgMap;
msgMap.insert(pair<UINT, decltype(func)>(nMsg, func));
}
## 32 Range-for loop for(类型 x:表达式
```cpp
例如: for(auto& i:v)//v=std::vecto
类型前面可以有一些属性修饰符,比如[[maybe_unused]]
详情见属性一条
和标准库中的 for_each 类似
关键字 noexcept 表明是否会抛出异常
noexcept 不会抛出异常 noexcept(false) 可能抛出异常
默认特殊成员函数处理 =default =delete throw
关键字 override 成员函数后缀修饰符,覆盖父类的虚函数(覆盖的函数必须是 virtual 函数)
关键字 final 类型和成员函数后缀修饰符
用在成员函数时,表示子类无法覆盖的方法
用在类型时,表示该类型不会有派生类型
获取对象的类型并用来声明另外一个变量
decltype(x)表示 x 的类
decltype((x))表示 x 的类型的引用