C++11 constexpr

在编译过程中就已经把值计算出来,会做类型检查; define 是在预编译过程中进行简单的文本替换,不会做类型检查; 在对象声明时或非静态成员函数中使用 constexpr 关键字(C++ 14)暗示这个对象或非静态成员函数是 const 的; 在函数或静态数据成员(C++ 17)声明中使用的 constexpr 关键字意味着内联; C++11 中 constexpr 函数可以使用递归,?: 三目运算符,从 C++14 开始,constexpr 函数可以在内部使用局部变量、循环和分支等简单语句; constexpr 修饰的是函数参数,而不是函数返回值,函数返回值是可以被改变的 constexpr 修饰变量必须满足以下要求: 它的类型必须是一个LiteralType 它必须立即初始化 其初始化的完整表达式,包括所有隐式转换、构造函数调用等,必须是 constexpr 它必须有 constexpr 析构 constexpr 修饰函数必须满足以下要求: 它不能是 virtual 修饰的(直到 C++20) 它不能是 coroutine 协程(直到 C++20) 它的返回类型(如果有的话)必须是 LiteralType 所有参数必须是 LiteralType class Test{ public: int x = 10; }; int main() { constexpr Test t; // const cout << typeid(t....

April 9, 2022 · 1 min · Rick Cui

C++11 std::function

包装指定调用标签(如 double(double) 返回值类型为 double,参数也是 double 类型)的函数; 替代以前的函数指针、函数对象和 lambda 表达式; 类模板 std::function 是一个通用的多态函数包装器。 function 的实例可以存储、复制和调用任何 CopyConstructible Callable 目标: 函数 lambda 表达式 std::bind 表达式 函数对象 指向成员函数的指针 指向成员属性的指针 可以减少生成的模板函数实例化代码的数量,缩小可执行文件的大小; 参考: std::function

April 8, 2022 · 1 min · Rick Cui

C++11 std::mem_fn

April 8, 2022 · 0 min · Rick Cui

C++11 std::reference_wrapper

创建一个对象或函数的引用,对象必须是 可复制(CopyConstructible)、可赋值(CopyAssignable) 的。 它经常被用作在标准容器(如 std::vector )中存储引用的机制,而标准容器通常不能保存引用。 辅助函数 std::ref 与 std::cref 常用于生成 std::reference_wrapper 对象。 std::reference_wrapper 也用于按引用传递参数给 std::bind 或 std::thread 的构造函数。 能隐式转换成 T&。 在 vector 中存储引用类型: #include <iostream>#include <list>#include <vector>#include <random>#include <functional>#include <algorithm> int main() { std::list<int> l(10); std::iota(l.begin(), l.end(), -4); // 从 -4 开始,逐个 +1 std::vector<std::reference_wrapper<int>> v(l.begin(), l.end()); // 不能在 list 上用 shuffle (要求随机访问),但能在 vector 上使用它 std::shuffle(v....

April 7, 2022 · 4 min · Rick Cui

C++11 std::ref, std::cref 与 std::bind

函数模板 ref 与 cref 是生成 std::reference_wrapper 类型对象的帮助函数,主要是与 std::bind 一起使用,默认情况下,std::bind 无法使用变量引用传递,即使原来的函数形参是引用类型的 void f(int& n1, int& n2, const int& n3) { std::cout << "In function: " << n1 << ' ' << n2 << ' ' << n3 << '\n'; ++n1; // 增加存储于函数对象的 n1 副本 ++n2; // 增加 main() 的 n2 // ++n3; // 编译错误 error: increment of read-only reference ‘n3’ } int main() { int n1 = 1, n2 = 2, n3 = 3; // 函数对象 bound_f // 默认会将此时变量值的副本做为函数对象的参数(函数参数特例化) std::function<void()> bound_f = std::bind(f, n1, std::ref(n2), std::cref(n3)); n1 = 10; n2 = 11; n3 = 12; std::cout << "Before function: " << n1 << ' ' << n2 << ' ' << n3 << '\n'; bound_f(); std::cout << "After function: " << n1 << ' ' << n2 << ' ' << n3 << '\n'; } 输出:...

April 7, 2022 · 1 min · Rick Cui