1.auto auto是旧关键字,在C++11之前,auto用来声明自动变量,表明变量存储在栈,很少使用。在C++11中被赋予了新的含义和作用,用于类型推断。...auto关键字主要有两种用途:一是在变量定义时根据初始化表达式自动推断该变量的类型,二是在声明或定义函数时作为函数返回值的占位符,此时需要与关键字decltype连用。...auto不能用来声明函数的返回值。但如果函数有一个尾随的返回类型时,auto是可以出现在函数声明中返回值位置。...在实际开发中,建议大家重写继承而来的虚函数时,加上关键字virtual表明当前函数是虚函数,C++编译器的“放纵”降低了代码可读性。...,用编译器来强制保证一些契约,改善编译信息的可读性,尤其是用于模板的时候; (3)编译器在遇到一个static_assert语句时,通常立刻将其第一个参数作为常量表达式进行演算。
安全性高:由于使用了 const 关键字,这个字符串变量是不可修改的,可以避免意外的修改和安全问题。 生命周期长:静态变量的生命周期从程序启动到结束,不受函数的调用和返回影响。...在实际编程中,还是不太建议使用全局静态对象,建议的写法: 要声明全局的常量字符串,可以使用 const 关键字和 extern 关键字的组合: // constants.h extern const char...; constexpr char* kVal="hahhahah"; 使用 constexpr 关键字来声明全局的常量字符串: // constants.h constexpr const char...除此之外,const 还能声明在成员函数上,const 被放在了函数的后面,表示这个函数是一个“常量”,函数的执行过程是 const 的,不会修改成员变量。...如果初始化由构造函数执行,则必须将构造函数声明为constexpr. ● 当满足这两个条件时,可以声明引用constexpr:引用的对象由常量表达式初始化,并且在初始化期间调用的任何隐式转换也是常量表达式
在使用标识符时还有注意以下几点: 标识符的长度最好不要超过8位,因为在某些版本的C中规定标识符前8位有效,当两个标识符前8位相同时,则被认为是同一个标识符。 标识符是严格区分大小写的。...强制类型转换 强制类型转换是通过定义类型转换运算来实现的。...其一般形式为: (数据类型) (表达式) 其作用是把表达式的运算结果强制转换成类型说明符所表示的类型 在使用强制转换时应注意以下问题: 数据类型和表达式都必须加括号, 如把(int)(x/2+y)写成...,在宏展开时又以该字符串取代宏名,这只是一种简单的代换,字符串中可以含任何字符,可以是常数,也可以是表达式,预处理程序对它不作任何检查。...constexpr函数必须满足下述限制: 函数返回值不能是void类型 函数体不能声明变量或定义新的类型 函数体只能包含声明、null语句或者一条return语句 在形参实参结合后,return语句中的表达式为常量表达式
1.auto auto是旧关键字,在C++11之前,auto用来声明自动变量,表明变量存储在栈,很少使用。在C++11中被赋予了新的含义和作用,用于类型推断。...auto关键字主要有两种用途:一是在变量定义时根据初始化表达式自动推断该变量的类型,二是在声明或定义函数时作为函数返回值的占位符,此时需要与关键字decltype连用。...auto不能用来声明函数的返回值。但如果函数有一个尾随的返回类型时,auto是可以出现在函数声明中返回值位置。...必须明确一点,在constexpr声明中,如果定义了一个指针,限定符号constexpr仅仅对指针有效,与指针所指对象无关。...C++引入的default关键字,可显示地、强制地要求编译器为我们生成默认版本。
constexpr constexpr的隐含意思是在编译阶段求值,对于一些求值操作,如果声明为constexpr,那么会编译器会尝试在编译阶段进行计算求值,如果求值成功,则用结果进行替换。...0; } 因为num被声明为constexpr,所以正如前面所说,在编译阶段求值,又因为i是一个非常量表达式,所以编译器报错如下: : In function 'int main()'...: Vector(int sz); } 可以使用Vector v = 3;这种方式进行初始化,往往这种并不是我们希望看到的,所以可以使用关键字explicit来强制显式初始化: class Vector...在这个语法中,"hello"是字符串字面值,而"s"是用户定义字面量的后缀,它将字符串字面值转换为std::string对象。...自gcc5.1之后,字符串优化采用了新的机制,即SSO,其为Small String Optimization的简写,中文译为小字符串优化,基本原理是:当分配大小小于16个字节时候,从栈上进行分配,而如果大于等于
由单引号括起来的一个字符是char类型的字面值,双引号括起来的0个或者多个字符则构成字符串字面值常量。...针对这种需求我们可以使用const关键字 const修饰的变量无法被修改(但是只在语法层面上,可以通过类型转换的方式强制将其指针修改为非const的) const对象无法修改,所以const对象需要初始化...如果想要定义的const变量在所有文件中都有效,不管在其定义还是声明语句前都加上extern关键字 //1.cpp extern const int g_i = 10; //在定义的同时也加上extern...非底层const可以赋值给底层const,而底层const无法赋值称为非底层const 在执行拷贝操作时,源对象可以是const或者非const、而目标对象只能是非const constexpr 和常量表达式...,无法确定是否是常量表达式,我们可以在需要定义常量表达式的情况下使用 constexpr关键字,该关键字是用来修饰一个常量表达式,如果对应的语句不是一个常量表达式,编译器会报错,可以根据这个报错进行修改
short没有对应值 两个字符串之间若没有逗号等运算符隔开,将会自动合并为一个字符串,这一点可以用来让cout在代码中分行 \v是纵向制表符,也就是在转移为下一列的情况下换行打印 \f是换页符,一般效果类似换行符...在分离式编译时,需要在不同文件中共享一个变量就需要声明它。...只有一个下划线作为标识符是合法的哦 尽量在要开始使用一个标识时才开始声明这个标识 ? 2.3.1 在声明的变量标识符前加一个&号,这个标识符就成为指向其后的对象的引用(reference)。...关键之来强制指定一个表达式是常量表达式,不是时无法通过检查 指针和引用都可以被定义为constexpr,但是指针的初始值必须是0之类的固定内存内的值 ?...2.5 传统中想要声明类型别名(type alias)使用的是typedef关键字,在C11中又引入了别名声明(alias declaration),关键字using,其作用是将等号左侧的名字规定为右侧类型的别名
thread_local修饰的变量可不进行初始化 例子: const char * get_str1() { return "111111"; } constexpr const char... constinit thread_local const char *str6; // 编译正确 return 0; } 2 语法 2.1 位域变量的默认成员初始化 位域变量在声明时可进行初始化... 因为模板参数是处于编译期计算的,因此,作为调用用于自定义类型的模板参数的成员函数时,这些成员必须是constexpr修饰的。 ..."; // 大写U是utf-32字符串 return 0; } 2.26 允许转换成未知边界的数组 这个特性比较简单,在实参为数组的传参时形参可以是无边界的数组。 ... 在以下的复制操作中,将会隐式采用移动操作代替复制操作的情况: ①如果return或co_return中的表达式是一个id-expression,其是在函数的最内层语句块或lambda表达式的主体或者参数声明子句中声明的隐式可移动实体
但实际上两者并没有什么高低之处 const大多数时候比define要更好,速度也更快 当需要在多文件中共享一个常量时,最好的做法是在一个单独的文件中定义一个const并加上extern符,然后在需要使用的文件中声明这个...关键字 如果表达式是decltype((x)),则返回的类型永远是引用,而没有双层括号时才是按照x本身状态来判断 3 字符串,向量和数组 命名空间实际上可以使用using namespace::name...,a>A string的构造函数的参数可以是(num,char),从而得到重复了num次的char字符串 size_type格式的,是一个机器无关的足以放下任何string的无符号整形数 append(...成员前用mutable关键字,使得这个成员必定不会变为const,即使身处const函数之中也可以被改变 友元函数没有传递性 声明重载函数为友元时,每一种重载都要分别声明一次 定义函数时,一旦遇到类名...构造函数,成员若有类内初始值则必由字面值常量或其自己的constexpr构造且类必须使用默认的析构函数的类,称为字面值常量类 static关键字只出现在类的声明里,不能在外部重复这个关键字,最好将其定义与其他非内联函数放在一起以保证唯一次定义
一、模板的定义 template 以关键字template开头,后面跟一个模板参数列表,列表里面用逗号将多个模板参数隔开定义的注意事项 模板的编译 当编译器遇到一个模板定义时,...只有当实例化处模板的一个特定版本时,编译器才会生成代码 重点:通常,当我们调用一个函数/定义实例化一个类时,编译器只需掌握函数的声明/类的声明即可,因此可以把函数/类的声明放置在头文件,而把函数/类的定义放置在源文件中...(是模板) 模板函数:调用函数模板时生成的函数(是函数),也称为函数模板的实例化 一个模板参数列表只和一个函数模板相对应。...但是这些关键字必须放在函数的返回值类型前面,模板参数列表的后面 template //正确inline T func(T const&);constexpr template //错误,constexpr位置错误T func2(T const&); 六、定义类型无关的代码 当我们定义函数模板时,如果函数能处理的功能只限于一些特定的情况,而不能作用于大多数的情况
单引号括起来表示char字面值,双引号括出的单个或者多个字符则构成字符串。 转义序列是还是比较常用的,最常用的是 \n, \t, \a, \r 分别是换行,横向制表,响铃,回车。...规则: 定义于任何函数体之外的变量都会被初始化为0,定义在函数内部的内置类型变量将不被初始化,如果试图拷贝或者复制,将会报错! 声明。...使用extern关键字可以只表示声明而非定义,比如extern int j;就指标是声明j,在后面的代码中还可以定义int j=0;,这样都是正确的,特别的,任何进行了显式初始化的声明即成为定义,且函数内部不允许使用这样的...constexpr 表达式: 实际中允许将变量声明为constexpr类型的类型,由编译器来验证变量的值是否是一个常量表达式,这样声明表示变量一定是个常量,且必须由常量表达式来初始化。...必须声明:constexpr声明中如果定义了一个指针,那么限定符仅对指针有效,与指针所指的对象无关。
const,当创建const对象时,对象是在构造初始化完成后(执行构造函数体前的瞬间)获得const属性的 当没有任何构造函数时编译器会默认生成一个构造函数,初始化(值初始化,默认构造或用初始值赋值)类内的各种成员...7.3 类的其他特性 用来定义类型的成员必须先定义再使用 在成员前用mutable关键字,使得这个成员必定不会变为const,即使身处const函数之中也可以被改变 提供类内初始值必须用等号或花括号 const...前面说到即使在类内声明了友元也要在外部提供相应的声明,这是因为我们需要友元函数在外部被使用/引用时,也处于正确的作用域之中,不过很多编译器并不强制要求这一点而是进行了优化 7.4 类的作用域 定义函数时...(string a)时,当我们输入的a是string类来调用Test(a),则编译器会隐式将string转为OurString再调用Test,但当我们输入的a是char*的“abcde”时,由于编译器需要先把...const属性的初始值或用constexpr来初始化 要注意由于静态变量不是由构造函数初始化的,一般来说我们不能在类内初始化它,而是在类内声明它然后在类外定义并初始化它 由于类内的它的初始化只是声明而已
其中 Text Formatting 是一个我个人比较感兴趣的新组件。它主要是解决了之前字符串格式化库 ( printf 系 ) 的效率问题和运行时安全的问题。 并且新的格式设置的形式也比较友好。...就在在GCC和Clang下,fmtlib 可以编译期验证输入格式字符串的合法性。 但是这个特性在 fmtlib 8.0 开始有一个很大的变化。 首先,是各类format接口变成了这种形式。...它的含义是可在编译期求值(注意和 const 关键字区分开来,一个函数和类型申明可以是 consteval 但不是 const 的)。...在使用 format_log(caller, "Hello {}", "world") 时。FMT 会被推断为 const char[9]& 。然后传给 fmt::format_to_n(...) 。...的调用其实就不再是编译期可以求值的 constexpr 了(因为上层的函数签名没有这个保证)。
+++>++>+>->>+[>. >---.+++++++..+++.>>.>+.>++. )); 而两者背后实现的算法是一致的...void push(char c) { data_[idx_++] = c; } constexpr operator const char*() const { return data_;...parse函数,解析BrainFuck代码,经典的递归下降分析: template constexpr auto parse(const char* input, bool...C++版本实现过程中可以先不加constexpr关键字,通过打印等debug手段调试通过后,最终加上constexpr关键字即可,最后既可以在运行时使用,也可以在编译时使用。...而Rust的过程宏只能用在编译时,无法用在运行时,而且只支持字面量方式,不支持变量传参给过程宏。
在使用数组时注意一下几点: 1.数组的维度必须是常量表达式,在编译时是已知的。...int a[size/getsize()]={1,2,3}; 2.数组的类型不能使用auto关键字推断类型。 3.显示初始化数组元素时,可省略数组的维度。...auto(nums) p1; // p2 是一个字符串数组 decltype(nums) p2 = {"c","d"}; //C++11引入新的标准,来获得数组的首元素地址和末尾元素的下一个位置的地址。...由于拷贝大的类型对象或者容器对象比较低效,甚至有的类型(IO类型)是不支持拷贝的,这时我们尽量采用按引用传递,这样可以避免拷贝付出的代价。如果函数内无须改变参数的值时,最好将其声明为常量引用。...由于这样声明太过于麻烦,所以在c++11标准中通过尾置返回类型,任何函数都能使用尾置返回类型。上述的声明可以通过: auto func(int i)->int(*)[10]
很多C++的初学者看到const这个关键字的第一反应都是一头雾水,主要是因为const可以出现在很多的位置,以及后面加入的constexpr更是常常感到困惑,今天就为大家一一解释出现它们的含义和以及作用...很多的全局变量都是通过常量来进行修饰,需要注意的是,使用const关键字修饰的变量需要立刻初始化 // 修饰局部变量,全局变量,成员变量 const int a = 2; // 错误,表达式必须是可修改的左值...引用 这是const最常用的一种方式,通常用于函数的参数列表中,因为我们知道在C++中函数参数有3中传递方式,分别是值传递,指针传递(或者叫地址传递),引用传递,前两种在传递时都会发成拷贝行为 指针本身也是一个变量...所以为了避免意外修改导致实参的值发生改,通常会采用const加上引用的方式传递参数 void test(const Student &s) { ... } constexpr关键字 constexpr...是C++11中引入的一个关键字,它的作用主要是用来修饰一些函数和变量,使其成为常量表达式,从而在编译器就可以进行计算,进一步提高程序运行期的效率 常量表达式:指的是有一个或多个常量组成的表达式,在实际开发中经常会接触到常量表达式
结构化绑定是指将array、tuple或struct的成员绑定到一组变量*上的语法,最常用的场景是在遍历map/unordered_map时不用再声明一个中间变量了: // pre c++17 for(...,将仅用于if语句内部的变量声明在if内,有助于提升代码的可读性。...std::string_view对字符串不具有所有权,且兼容std::string和const char*两种类型。...如果传入的是明文字符串const char*, const std::string&需要进行一次内存分配,将字符串拷贝到堆上,而std::string_view则可以避免。...void*时,T的类型信息就已经丢失了,在转换回具体类型时程序无法判断当前的void*的类型是否真的是T,容易带来安全隐患。
包含零个形参时,可以使用void标记 对于非模板函数来说,其每个形参都有确定的类型,但形参可以没有名称 形参名称的变化并不会引入函数的不同版本 实参到形参的拷贝求值顺序不定,C++17强制...在一个翻译单元中,每个形参的缺省实参只能定义一次 具有缺省实参的函数调用时,传入的实参会按照从左到右的顺序匹配形参 缺省实参为对象时 ,传入的缺省值会随对象值的变化而变化 main函数的两个版本 无形参版本...因为obj在是Str对象,所以会去MyNS域中查找 重载解析:在名称查找的基础上进一步选择合适的调用函数 过滤不能被调用的版本(non-viable candidates)...参数个数不对 无法将实参转换为形参 实参不满足形参的限制条件 在剩余版本中查找与调用表达式最匹配的版本,匹配级别越低越好(有特殊规则) 级别1:完美匹配 或 平凡转换(比如加一个const) 级别2:...4.inline关键字声明一定要有函数定义。
bool b1=true;: 声明一个布尔型变量b1并初始化为true。在C++中,布尔类型的值只能是true或false。...const string myname="Tridib";: 声明一个常量字符串变量myname并初始化为"Tridib"。const关键字表示该变量的值不能被修改。...char str[] = "Hello";:定义一个包含字符串"Hello"的字符数组。...常量和常量表达式 常量:使用const关键字定义常量,其值在程序运行期间不可改变。...例如,const int kConstantExpression = 4 * 7;是常量表达式,而const int kVariableExpression = k + 1;不是常量表达式,因为k的值在编译时无法确定
编译期会将字符串常量存储在一个全局区,然后再使用字符串常量的位置用一个指针代替。所以基本可以等价认为,字符串常量(字面量)是const char *类型。...类型推导问题 在进行类型推导时,字符串常量会按const char *来处理,有时会导致问题,比如: template void f(T t) { std::cout <<...指针意义不明问题 由于 C++保留了 C 风格字符串的行为,因此在很多场景下,把const char *就默认为了字符串,都会按照字符串去解析。...,打印指针的值 std::cout << &b << std::endl; // 流接收char *,按字符串处理 } STL 中所有流接收到char *或const char *时,并不会按指针来解析...但换成常量表达式时,constexpr要放在最前,因此不能写成const char *constexpr str,而是要写成constexpr const char *str。
领取专属 10元无门槛券
手把手带您无忧上云