type
status
date
slug
summary
tags
category
icon
password

Modern C++

Modern C++指的是C++11/C++14/C++17/C++20等版本,新增和改进了C++语法,提升开发效率.

nullptr

nullptr是用来替换NULL的

constexpr

常量表达式
constexpr int num = 1 + 2+ 3;

if/switch 变量声明强化

if (int i = num - 1){ }
即判断条件中可以直接声明临时变量.

初始化列表

#include <iostream> #include <string> using namespace std; class Person { public: string name; int age; int sex; const string &getName() const { return name; } int getAge() const { return age; } int getSex() const { return sex; } }; void testInit() { Person person = {"jack", 18, 1}; }
C++11之前的版本初始化比较麻烦,需要写一些无用代码,这之后比较灵活,可以按照上面的方式进行初始化.

结构化绑定

即多返回值的封包/拆包,在Python,Go,Kotlin中比较常见.
#include <iostream> #include <tuple> using namespace std; void testTuple() { auto[x, y, z] = make_tuple(1, false, "hello"); cout << x << y << z << endl; }

auto

即类型推断,不用每个变量声明都声明类型.
需要注意的就是:auto不能用于函数传参,也不能用于推导数组类型

decltype

auto只能用于变量的类型推断,decltype则对表达式类型推断做了补充.
auto x = 1; auto y = 2; decltype(x+y) z;

区间for迭代

#include <iostream> #include <vector> #include <algorithm> int main() { std::vector<int> vec = {1, 2, 3, 4}; if (auto itr = std::find(vec.begin(), vec.end(), 3); itr != vec.end()) *itr = 4; for (auto element : vec) std::cout << element << std::endl; // read only for (auto &element : vec) { element += 1; // writeable } for (auto element : vec) std::cout << element << std::endl; // read only }

模板

将一切能在编译期解决的问题放在编译期解决,仅在运行时处理核心的动态服务.

外部模板

template class std::vector<bool>; // 强行实例化 extern template class std::vector<double>; // 不在该当前编译文件中实例化模板
其实就是一个实例化时机的问题.

类型别名模板

模板是用来生成类型的.
类型别名一般这样用:
typedef 原名称 新名称
对于复杂一点的就显得很难看,可以使用using:
typedef int (*process)(void *); using NewProcess = int(*)(void *); template<typename T> using TrueDarkMagic = MagicType<std::vector<T>, std::string>; int main() { TrueDarkMagic<bool> you; }

委托构造

#include <iostream> class Base { public: int value1; int value2; Base() { value1 = 1; } Base(int value) : Base() { // 委托 Base() 构造函数 value2 = value; } }; int main() { Base b(2); std::cout << b.value1 << std::endl; std::cout << b.value2 << std::endl; }
没什么好说的,其他语言在设计的时候就已经支持了.

继承构造

#include <iostream> class Base { public: int value1; int value2; Base() { value1 = 1; } Base(int value) : Base() { // 委托 Base() 构造函数 value2 = value; } }; class Subclass : public Base { public: using Base::Base; // 继承构造 }; int main() { Subclass s(3); std::cout << s.value1 << std::endl; std::cout << s.value2 << std::endl; }

overide , final

struct Base { virtual void foo(int); }; struct SubClass: Base { virtual void foo(int) override; // 合法 virtual void foo(float) override; // 非法, 父类没有此虚函数 };
struct Base { virtual void foo() final; }; struct SubClass1 final: Base { }; // 合法 struct SubClass2 : SubClass1 { }; // 非法, SubClass1 已 final struct SubClass3: Base { void foo(); // 非法, foo 已 final };
这两点也没什么好说的,其他语言早就支持了.

Lambda

[捕获列表](参数列表) mutable(可选) 异常属性 -> 返回类型 { // 函数体 }

值捕获

void lambda_value_capture() { int value = 1; auto copy_value = [value] { return value; }; value = 100; auto stored_value = copy_value(); std::cout << "stored_value = " << stored_value << std::endl; // 这时, stored_value == 1, 而 value == 100. // 因为 copy_value 在创建时就保存了一份 value 的拷贝 }

引用捕获

void lambda_reference_capture() { int value = 1; auto copy_value = [&value] { return value; }; value = 100; auto stored_value = copy_value(); std::cout << "stored_value = " << stored_value << std::endl; // 这时, stored_value == 100, value == 100. // 因为 copy_value 保存的是引用 }

范型Lambda

auto add = [](auto x, auto y) { return x+y; }; add(1, 2); add(1.1, 2.2);

函数对象包装器

如果不使用std::fucntion()是这样子的:
#include <iostream> using foo = void(int); // 定义函数类型, using 的使用见上一节中的别名语法 void functional(foo f) { // 定义在参数列表中的函数类型 foo 被视为退化后的函数指针类型 foo* f(1); // 通过函数指针调用函数 } int main() { auto f = [](int value) { std::cout << value << std::endl; }; functional(f); // 传递闭包对象,隐式转换为 foo* 类型的函数指针值 f(1); // lambda 表达式调用 return 0; }
使用了之后是这样的:
#include <functional> #include <iostream> int foo(int para) { return para; } int main() { // std::function 包装了一个返回值为 int, 参数为 int 的函数 std::function<int(int)> func = foo; int important = 10; std::function<int(int)> func2 = [&](int value) -> int { return 1+value+important; }; std::cout << func(10) << std::endl; std::cout << func2(10) << std::endl; }
XML文件解析CMake的简单使用说明
姜康
姜康
一个软件工程师
公告
type
status
date
slug
summary
tags
category
icon
password
🎉博客网站重新制作了🎉
👏欢迎更新体验👏