• 1. C++11
    • 1.1. nullptr常量
    • 1.2. constexpr关键字
    • 1.3. using类型别名声明
    • 1.4. auto关键字
    • 1.5. 范围for语句
    • 1.6. lambda表达式与std::bind
    • 1.7. =default/=delete
    • 1.8. 右值引用与移动语义
    • 1.9. explicit/override/final/noexcept指示符
    • 1.10. string数值转换函数
    • 1.11. std::array
    • 1.12. 无序关联容器
    • 1.13. 智能指针
    • 1.14. std::function
  • 2. C++14
    • 2.1. std::make_unique()
    • 2.2. 泛型lambda/初始化捕获
    • 2.3. 更加宽松的constexpr函数
    • 2.4. 二进制字面值和数字分隔符
  • 3. C++17
    • 3.1. 结构化绑定
    • 3.1. 条件分支语句初始化
    • 3.1. std::filesystem
    • 3.1. std::string_view
    • 3.1. std::optional
    • 3.1. std::any
    • 3.1. std::variant
  • 参考资料

1. C++11

1.1. nullptr常量

  • 说明:nullptr是nullptr_t类型的字面值,代表空指针,它可以被转换成任一其他的指针类型
  • 对比:
    1. 指针初始化为空指针:
        int* p1 = 0;        // C++98int* p2 = NULL;     // C++98int* p3 = nullptr;  // C++11
    
    1. 函数调用:
        void F(int);void F(void*);void Func() {F(0);           // 调用void F(int)F(NULL);        // 可能调用void F(int),取决于NULL的宏定义值F(nullptr);     // 调用void F(void*)}
    
  • 建议:优先选用nullptr, 而非0或NULL

1.2. constexpr关键字

  • 说明:
    1. 算术类型,引用,指针类型属于字面值类型
    2. constexpr用于声明变量时表示该变量是一个编译期常量,变量必须是字面值类型
    3. constexpr用于声明函数时表示该函数可以在编译期得出运算结果
    4. C++11中constexpr函数必须遵守以下约定,在C++14中有所放宽:
      1. 函数的返回类型和形参类型都必须是字面值类型
      2. 函数体只能是一条return语句,其他语句不能在运行时执行任何操作,例如空语句,类型别名声明语句等
    5. 调用constexpr函数时,如果传入的参数都是编译期常量,则函数结果将在编译期计算出来;如果传入参数有一个到多个的值编译期未知,则运作方式与普通函数无异
  • 对比:
    1. constexpr与const比较:constexpr对象一定是const对象,反之不成立
        int Add1(int a, int b);             // 普通函数constexpr int Add2(int a, int b);   // constexpr函数void Func() {const int c1 = 10;          // 编译期常量const int c2 = c1 + 1;      // 编译期常量const int c3 = Add1(1, 2);  // 运行时常量int x1 = 10;                // 非常量constexpr int ce1 = 10;             // 编译期常量constexpr int ce2 = ce1 + 1;        // 编译期常量// constexpr int ce3 = Add1(1, 2);  // 编译出错,Add1无法在编译期计算出结果constexpr int ce4 = Add2(1, ce1);   // 正确, 1和ce1都是编译期常量,Add2将在编译期计算出结果// constexpr int ce5 = Add2(1, x1); // 错误, x1不是编译期常量,Add2运作方式与Add1相同// 定义数组,数组维度必须是编译期常量int arr1[10];       // 正确int arr2[c1];       // 正确// int arr3[c3];    // 错误// int arr4[x1];    // 错误int arr5[ce1];      // 正确}
    
  • 建议:
    1. 如果认为变量是一个编译期常量,就为变量加上constexpr声明
    2. 只要有可能,就为函数加上constexpr声明

1.3. using类型别名声明

  • 说明:为某种类型定义另外一个名字, 格式: using alias = type;
  • 对比:
    1. using与typedef比较:
        // 为char*定义别名typedef char* cstring;using cstring = char*;// 定义函数指针类型别名typedef void(*pFunc)(int, int);     // pFunc是函数指针类型using pFunc = void(*)(int, int);    // pFunc是函数指针类型using Func = void(int, int);        // Func是函数类型, 不是指针类型,需要注意
    
  • 建议:
    1. 优先使用using进行别名声明,using声明更加直观易懂
    2. 不要使用#define定义类型别名,宏仅仅是字符串,没有类型信息

1.4. auto关键字

  • 说明:
    1. 使用auto定义变量时,编译器根据初始化表达式自动推导变量类型,因此变量必须初始化
    2. 使用auto可以定义持有lambda表达式的变量
  • 对比:
    1. 变量定义
        void Func() {// 初始化int x1;                 // 未初始化,存在风险// auto x2;             // 编译错误auto x3 = 4;            // x3是int类型auto x4 = x3;           // x4是int类型,拷贝x3的值auto& x5 = x3;          // x5是int&类型,指向x3const auto& x5 = x3;    // x6是const int&类型,指向x3// 避免类型转换std::vector<int> vec = {1, 2, 3, 4};int count1 = vec.size();    // 发生隐式类型转换, 编译告警auto count2 = vec.size();   // 正确接收size()函数的返回值// 简化变量定义std::map<int, std::string> int2StrMap;int2StrMap.insert(std::make_pair(1, "hello"));std::map<int, std::string>::iterator iter1 = int2StrMap.begin();    // C++98auto iter2 = int2StrMap.begin();                                    // C++11// 接收lambda表达式std::function<int(int)> func = [](int a) {return 5 + a;};auto lambda1 = [](int a) {return 5 + a;};}
    
  • 建议:
    1. 优先使用auto声明变量, 而非显式型别。可以简化定义,保证变量被初始化,消除型别不匹配问题
    2. 当使用大括号表达式初始化auto声明的变量时, 变量类型会被推导为std::initializer_list

1.5. 范围for语句

  • 说明:
    1. 范围for语句可以用来遍历容器的所有元素,格式为:
        for (declaration : expression) {statement}
    
    1. 范围for语句用于包含能返回迭代器的begin()和end()成员的对象
  • 对比:
    1. 遍历容器:
        std::vector<int> vec = {1, 2, 3, 4, 5, 6, 7, 8, 9};// C++98for (std::vector<int>::iterator iter1 = vec.begin(); iter1 != vec.end(); ++iter1) {std::cout << *iter;}for (int i = 0; i < vec.size(); ++i>) {std::cout << vec[i];}// C++11for (auto val : vec) {std::cout << val;}
    
  • 建议:
    1. 当需要遍历整个容器而不需要元素的索引时,使用范围for语句而不是迭代器
    2. 当在范围for语句中使用auto时,内置类型的元素直接使用auto,需要修改元素时使用auto&,不需要修改元素时使用const auto&
    3. 一定不要在范围for语句中增删容器元素

1.6. lambda表达式与std::bind

  • 说明:
    1. 一个lambda表达式表示一个可调用的代码块,可以理解为一个匿名函数,其格式为:
        // 捕获列表中为lambda所在函数中定义的局部变量,如果没有mutable声明,则不能修改这些捕获的变量// 形参列表,返回类型,函数体与其他普通函数一样[捕获列表](形参列表) mutable -> 返回类型 {函数体}
    
    1. lambda表达式的结构中可以忽略形参列表、返回类型和mutable声明,但必须包含捕获列表和函数体:
        void Func() {auto f = []{return 5;}// 调用lambda表达式std::cout << f() << std::endl;}
    
    1. 忽略返回类型时,如果函数体只是一个return语句,则返回类型根据表达式推导,否则返回void
    2. lambda表达式的形参列表中不能有默认参数
    3. lambda表达式的捕获列表只用于捕获函数中的局部非static变量,而局部static变量和函数之外声明的名字可以直接使用
    4. lambda捕获方式:
        void Func() {int x1 = 5;const int x2 = 10;// 显式值捕获auto lambda1 = [x1, x2](int a) {return x1 + x2 + a;};// 显式值捕获x1,显式引用捕获x2auto lambda2 = [x1, &x2](int a) {return x1 + x2 + a;};// 默认值捕获x1,x2auto lambda3 = [=](int a) {return x1 + x2 + a;};// 默认引用捕获x1,x2auto lambda4 = [&](int a) {return x1 + x2 + a;};// 默认值捕获x1,显式引用捕获x2auto lambda5 = [=, &x2](int a) {return x1 + x2 + a;};// 默认引用捕获x1,显式值捕获x2auto lambda6 = [&, x2](int a) {return x1 + x2 + a;};}
    
    1. lambda本质上是一个函数对象(重载了operator()的类的对象):
         int x = 10;auto lambda1 = [x](int a) {return x + a;};// 等价于class TempUniqueName {public:TempUniqueName(int x) : x_(x){}int operator()(int a) {return x_ + a;}private:int x_;};TempUniqueName lambda1(x);
    
    1. std::bind是std::bind1st和std::bind2nd的后继特性, 它接受一个可调用对象,返回一个新的可调用对象以新的形参列表, 其格式为:
        auto newCallable = std::bind(callable, argList);
    
  • 对比:
    1. lambda,函数指针,函数对象比较:
        bool IntCompare(int a, int b) {return a > b;}class IntComparator {public:bool operator()(int a,int b) {return a > b;}}void Func() {std::vector<int> vec = {1, 2, 3, 4, 5, 6, 7, 8, 9};// 函数指针std::sort(vec.begin(), vec.end(), IntCompare);// 函数对象std::sort(vec.begin(), vec.end(), IntComparator());// lambdastd::sort(vec.begin(), vec.end(), [](int a, int b){return a > b;});}
    
    1. lambda, std::bind比较:
        void F1(int a1, int a2, double b1, double b2);// 包装F1,使其只需传入a1和b1参数, a2和b2使用给定值void Func() {// std::bindauto newF1 = std::bind(F1, std::placeholders::_1, 100, std::placeholders::_2, 10.0);newF1(50, 20.0);    // 等价于F1(50, 100, 20.0, 10.0)// lambdaauto lambdaF1 = [](int a1, double b1) {F1(a1, 100, b1, 10.0);}lambdaF1(50, 20.0);}
    
  • 建议:
    1. 不要使用lambda的默认捕获方式,容易导致空悬指针问题
    2. 优先选用lambda,而不是std::bind:lambda可读性更好,表达力更强,可能运行效率也更高

1.7. =default/=delete

  • 说明:
    1. 对类的特种成员函数(默认构造函数,拷贝构造函数,拷贝赋值运算符,移动构造函数,移动赋值运算符,析构函数),可以使用=default来显式的要求编译器生成合成的版本,这些合成的版本会逐成员调用其对应的特种函数, 例如合成的默认构造函数: 对于内置类型,执行默认初始化(随机值),对于类类型,调用其默认构造函数
    2. 使用=default声明的函数是隐式内联的,如果不希望是内联函数,则需要将=default声明放在类外
    3. 对于任何函数(不仅是类的特种成员函数,虽然通常用于这些函数上)可以使用=delete要求编译器不定义这个函数,=delete声明必须出现在函数第一次声明的时候
    4. 如果类的析构函数被声明=delete,那么编译器将不允许创建该类型的变量或临时对象,因为无法销毁该类的成员
  • 对比:
        // = defaultclass DefaultMember {public:DefaultMember() = default;                      // 合成默认构造函数, 隐式内联DefaultMember(const DefaultMember&);            // 合成拷贝构造函数, 非内联DefaultMember& operator=(const DefaultMember&); // 合成拷贝赋值运算符,非内联~DefaultMember() = default;                     // 合成析构函数, 隐式内联};DefaultMember::DefaultMember(const DefaultMember&) = default;DefaultMember& DefaultMember::operator=(const DefaultMember&) = default;// = delete// C++98class NonCopyable1 {// 声明为private成员函数,不定义这些函数,无法访问,因此阻止了拷贝NonCopyable1(const NonCopyable1&);NonCopyable1& operator=(const NonCopyable1&);public:NonCopyable1();~NonCopyable1();};// C++11class NonCopyable2 {public:NonCopyable2();~NonCopyable2();// 删除的拷贝构造和拷贝赋值运算符NonCopyable2(const NonCopyable2&) = delete;NonCopyable2& operator=(const NonCopyable2&) = delete;};
    
  • 建议:
    1. 对于类的特种成员函数,如果希望使用编译器合成的版本,则使用=default显式声明这些函数
    2. 对于希望阻止拷贝的类应该使用=delete声明拷贝构造函数和拷贝赋值运算符,而不是将其声明为private成员

1.8. 右值引用与移动语义

  • 说明:
    1. 左值和右值:
      1. 左值:变量(包括形参,右值引用),函数,返回左值引用的函数调用,内建赋值表达式,前置自增自减表达式,指针解引用表达式,内建下标表达式,字符串字面量,强转为左值引用类型的表达式
      2. 右值:字面量(字符串字面量除外),返回非引用的函数调用,后置自增自减表达式,内建的算术表达式、逻辑表达式、比较表达式,取地址表达式,强转为非引用类型的表达式,枚举项,lambda表达式
    2. 右值引用就是必须绑定到右值的引用,使用&&表示, 右值引用不能绑定到一个左值上:
        int i = 42;int& r = i;             // r是左值引用// int&& rr = i;        // 错误, 右值引用不能绑定到左值// int& r2 = i * 42;    // 错误, i * 42是一个右值const int& r3 = i * 42; // 可以将const左值引用绑定到右值int&& rr2 = i * 42;     // rr2是右值引用// int&& rr3 = rr2;     // 错误, rr2也是左值
    
    1. 可以使用标准库函数std::move将一个左值转换成右值引用,当使用std::move后这个左值只能被赋值或销毁,而不能直接使用它:
        // 将左值i转换到右值,此后i可以被赋值,也可以直接销毁,在赋予i新值之前不能使用i的值int&& rr4 = std::move(i);
    
    1. 移动构造函数/移动赋值运算符:类的这两个特种成员函数的形参是该类对象的右值引用,在函数体中要完成资源的移动,同时还要确保移后对象处于这样一个状态-销毁它是无害的,一旦移动完成,源对象必须不再指向被移动的资源。这两个函数只进行资源的移动,而不进行资源分配,不会抛出异常,因此需要加上noexcept标识符,否则移动操作不会触发,编译器会转而调用拷贝操作:
        class Moveable {static constexpr int ARRAY_SIZE = 10;public:Moveable(int length = ARRAY_SIZE) : data_(new int[length]), len_(length){}~Moveable() {Free();}// 拷贝控制Moveable(const Moveable& other) : data_(new int[other.len_]), len_(other.len_) {for (int i = 0; i < len_; ++i) {data_[i] = other.data_[i];}}Moveable& operator=(const Moveable& other) {// copy and swap,能正确处理自赋值Moveable tmp(other);std::swap(data_, tmp.data_);std::swap(len_, tmp.len_);return *this;}// 移动控制Moveable(Moveable&& other) noexcept : data_(other.data_), len_(other.len_) {other.data_ = nullptr;other.len_ = 0;}Moveable& operator=(Moveable&& other) noexcept {// copy and swap,能正确处理自赋值Moveable tmp(std::move(other));std::swap(data_, tmp.data_);std::swap(len_, tmp.len_);return *this;}// 对于拷贝赋值运算符和移动赋值运算符,有一种简洁的实现方法// 形参为Moveable类型,对左值调用拷贝构造,对右值调用移动构造Moveable& operator=(Moveable other) {std::swap(data_, other.data_);std::swap(len_, other.len_);return *this;}private:void Free() {if (data_) {delete[] data_;}}private:int* data_;int len_;};
    
    1. 拷贝左值,移动右值,如果没有移动控制函数,那么对右值也将进行拷贝操作
  • 对比:
  • 建议:
    1. 对于使用std::move处理过的左值不要再使用其值
    2. 移动操作不是提高性能的灵药,应该假定移动操作不存在,成本高,未使用

1.9. explicit/override/final/noexcept指示符

  • 说明:

    1. 当类的构造函数只接受一个参数时,实际上定义了一种由该参数转换为该类类型的隐式转换规则,使用explicit可以抑制这种转换的发生:
        class ImplicitConvertable {public:ImplicitConvertable(const std::string&);};class ExplicitConvertable {public:explicit ExplicitConvertable(const std::string&);};void F1(const ImplicitConvertable& obj);void F2(const ExplicitConvertable& obj);void Func() {std::string str = "hello";F1(str);            // 正确,从str隐式构造一个ImplicitConvertable对象传入F1// F1("hello")      // 错误,编译器只会自动进行一步类型转换,这里需要两步转换F1(ImplicitConvertable(str));   //正确// F2(str);         // 错误,explicit抑制了隐式转换F2(ExplicitConvertable(str));    // 正确,只能显式构造ExplicitConvertable对象}
    
    1. 在继承体系中,可以使用override来显式说明意在重写基类中的虚函数:
        class Base {public:virtual void F1();      // 虚函数第一次出现的地方添加virtual关键字virtual void F2(int);};class Derived : public Base {public:void F1() override;     // 正确,重写基类虚函数void F1();// void F2() override;     // 错误,基类没有void F2()的虚函数// void F3() override;     // 错误,基类没有void F3()的虚函数virtual void F4();      // 正确, 派生类定义自己的虚函数};
    
    1. 使用final来阻止类被继承:
        class NoDerived final {};   // NoDerived不能被继承// class D : public NoDerived {};   // 错误, 不能从NoDerived继承
    
    1. 使用noexcept来制定一个函数不会抛出异常,这种函数可以简化调用处的代码,编译器也可以对该函数进行特殊优化.如果函数违反了异常说明而抛出了异常,那么程序将直接调用std::terminate结束程序:
        void Func() noexcept;   // 承诺Func不抛出异常
    
  • 对比:

  • 建议:

    1. 为类的单参数构造函数加上explicit指示符,可以防止隐式转换发生
    2. 在派生类中为想要改写的基类虚函数加上override指示符
    3. 为不想被继承的类加上final指示符
    4. 只要函数不抛出异常,就为其加上noexcept知识符

1.10. string数值转换函数

  • 说明:
    C++11中引入了一组用于数值和字符串之间相互转换的函数
  • 对比:
    1. 与C标准库字符串转换函数比较:
        // C库int atoi (const char * str);            // str转换到intlong int atol ( const char * str );     // str转换到longdouble atof (const char* str);          // str转换到double// C++std::string to_string (val);        // val转换到字符串, val可以是任何算数类型int stoi (const string&  str, size_t* idx = 0, int base = 10);  // str 转换到intlong stol (const string&  str, size_t* idx = 0, int base = 10); // str 转换到longfloat stof (const string&  str, size_t* idx = 0);               // str 转换到floatdouble stod (const string&  str, size_t* idx = 0);              // str 转换到double
    
  • 建议: 使用C++风格的转换函数

1.11. std::array

  • 说明:
    1. std::array与数组一样拥有固定大小,并且大小需要在编译期给定
    2. std::array不会像数组一样作为参数传递时退化为指针
  • 对比:
        void Func {// 内置数组int arr1[10] = {0};for (auto val : arr1) {std::cout << val;}for (int i = 0; i < 10; ++i>) {std::cout << arr1[i];}// std::arraystd::array<int, 10> arr2;arr2.fill(0);std::cout << arr2.front();std::cout << arr2.back();for (auto val : arr2) {std::cout << val;}for (int i = 0; i < arr2.size(); ++i>) {std::cout << arr2.at(i);}}
    
  • 建议:
    1. 如果需要固定大小的数组,那么应该使用std::array而不是内置数组, 因为std::array类型安全,提供了丰富的接口,性能与内置数组相同

1.12. 无序关联容器

  • 说明:
    1. C++11定义了4个无序关联容器:unordered_map, unordered_set, unordered_multimap, unordered_multiset, 分别与有序关联容器:map, set, multimap, multiset对应
    2. 无序关联容器底层使用hash表实现, 因此不能假定容器中元素的排列顺序;有序关联容器底层使用红黑树实现,所有元素按照键值大小排列,遵循严格弱序准则
    3. 对于自定义类型,如果需要放入无序关联容器内时,需要给定该类型的hash计算方式和判等准则;需要放入有序关联容器时,只需要给定符合严格弱序的比较准则
    4. 无序关联容器的插入,查找,删除操作时间复杂度为O(1);有序关联容器的插入,查找,删除操作时间复杂度为O(lg(n))
  • 对比:
        // 自定义类型class Data {public:int Val();const std::string& Str();private:int val_;std::string str_;};// 比较准则,用于有序关联容器struct DataCompare {bool operator()(const Data& l, const Data& r) const {return l.Val() < r.Val() ||((l.Val() == r.Val()) && l.Str() < r.Str());}};// hash函数,用于无序关联容器struct DataHash {size_t operator()(const Data& data) const {return std::hash<int>()(data.Val()) ^ std::hash<std::string>()(data.Str());}};// 判等准则,用于无序关联容器struct DataEqual {bool operator()(const Data& l, const Data& r) const {return (l.Val() == r.Val()) && (l.Str() == r.Str());}};void Func() {std::set<Data, DataCompare> orderedDataSet;std::unordered_set<Data, DataHash, DataEqual> unorderedDataSet;}
    
  • 建议:
    1. 如果元素的顺序不重要,优先使用无序关联容器

1.13. 智能指针

  • 说明:
    1. C++11提供了两种智能指针:std::shared_ptr和std::unique_ptr; 一种伴随类:std::weak_ptr, 只能配合std::shared_ptr使用
    2. std::shared_ptr提供了共享所有权语义,可以拷贝赋值多次,并且是线程安全的,当指向资源的最后一个shared_ptr销毁时,资源被释放
    3. std::unique_ptr提供了独占所有权语义,同一时刻,只能有一个unique_ptr对象指向资源,unique_ptr不可拷贝赋值,只能移动
    4. std::weak_ptr是一种弱引用, 指向shared_ptr管理的资源,但不拥有所有权,每次使用前需要检查资源是否有效
    5. std::shared_ptr的对象大小是固定的, std::unique_ptr的对象大小是不定的
  • 对比:
        // 自定义类型struct Data {Data() : val(0), str(){}Data(int v, const std::string& s) : val(v), str(s){}int val;std::string str;}void Func() {// std::uniqu_ptrstd::uniqu_ptr<Data> up1;       // 空指针std::uniqu_ptr<Data> up2(new Data());   // 持有一个指向默认构造的Data对象的指针std::uniqu_ptr<Data> up3 = std::make_unique<Data>();// C++14,持有一个指向默认构造的Data对象的指针auto up4 = std::make_unique<Data>(1, "hello"); // C++14, 持有一个指向Data(1,"hello")对象的指针// auto up5 = up2   // 错误, unique_ptr不可拷贝auto up6 = std::move(up2);  // 正确,unique_ptr可移动,资源所有权转移到up6, up2变成空指针// std::shared_ptr与std::weak_ptrstd::shared_ptr<Data> sp1;       // 空指针std::shared_ptr<Data> sp2(new Data());   // 持有一个指向默认构造的Data对象的指针std::shared_ptr<Data> sp3 = std::make_shared<Data>();// 持有一个指向默认构造的Data对象的指针auto sp4 = std::make_shared<Data>(1, "hello"); // 持有一个指向Data(1,"hello")对象的指针auto sp5 = sp2;     // 正确, shared_ptr可拷贝// auto sp6 = up3;  // 错误, 不能从unique_ptr拷贝资源auto sp7 = std::move(up3);  // 正确, 从unique_ptr移动资源std::weak_ptr<Data> wp1;    // 空指针std::weak_ptr<Data> wp2(sp2);    // 持有指向sp3所持资源的弱引用if (!wp2.expired()) {       // 判断与wp2关联的share_ptr是否已失效auto sp8 = wp2.lock();//若expired()为true, lock()返回空的shared_ptr,否则返回有效的shared_ptr}std::shared_ptr<Data> sp9(wp2); // 从weak_ptr构造shared_ptr, 如果若expired()为true则抛出异常}
    
  • 建议:
    1. 不要使用std::auto_ptr
    2. 优先使用std::unique_ptr, 因为unique_ptr有与原始指针相同的性能
    3. 优先使用std::make_unique()(C++14)和std::make_shared(), 因为只进行一次内存分配,内存占用更小,性能更好
    4. 使用std::weak_ptr来替代可能空悬的std::shared_ptr
    5. 使用std::weak_ptr来解决std::shared_ptr可能导致的指针环路

1.14. std::function

  • 说明:
    1. 可调用对象的概念: 函数,函数指针,函数对象,lambda表达式统称为可调用对象
    2. std::function内部可以保存一个可调用对象的副本,std::function对象本身也是可调用对象,调用std::function对象相当于调用其内部持有的可调用对象
  • 对比:
        // C++98, 一般只能通过函数指针传递可调用对象typedef int(*pAddFunc)(int, int);int Add(int a, int b) {return a + b;}void Invoke1(pAddFunc fn) {int val = fn(2, 3);std::cout << val;}void Func1() {Invoke1(Add);}// C++11using AddFunc = std::function<int(int, int)>;struct Adder {int operator()(int a, int b) {return a + b;}};void Invoke2(AddFunc fn) {int val = fn(2, 3);std::cout << val;}void Func2() {Invoke2(Add);Invoke2(Adder());Invoke2([](int a, int b) {return a + b;});}
    
  • 建议: 需要回调函数时,使用std::function接收可调用对象,而不是函数指针,可以简化调用逻辑

2. C++14

2.1. std::make_unique()

  • 说明:
    1. std::make_unique()在C++14中加入标准库,原因是在C++11时标准委员会忘记了~~~
    2. 使用方法见1.13
  • 对比:
  • 建议: 优先使用std::make_unique(),而非显式分配资源

2.2. 泛型lambda/初始化捕获

  • 说明:
    1. C++14中允许在lambda的形参列表中使用auto来接受任意类型的参数:
        // 可以接受任意类型的参数,只要该类型支持+运算void Func() {auto lambda1 = [](const auto& a, const auto& b) {return a + b;};}
    
    1. C++14中允许在lambda的捕获列表中使用初始化捕获的方式来捕获局部变量:
        void Func() {int num = 10;// 以初始化捕获的方式捕获局部变量num到val中// 需要注意: = 两侧是两个作用域, 左侧为lambda的作用域,右侧为函数的作用域auto lambda2 = [val = num](int a) {return val + a;};}
    
  • 对比:
    1. 泛型lambda:
        void Func() {// C++11, 有多少种类型,就需要定义多少种lambdastd::vector<int> intVec = {1, 2, 3, 4, 5};auto lambda1 = [](int a) {std::cout << a;};std::for_each(intVec.begin(), intVec.end(), lambda1);std::vector<double> doubleVec = {1.0, 2.0, 3.0, 4.0, 5.0};auto lambda2 = [](double a) {std::cout << a;};std::for_each(doubleVec.begin(), doubleVec.end(), lambda2);std::vector<std::string> strVec = {"hello, ", "zhong ", "dian ", "xing ", "fa"};auto lambda3 = [](std::string a) {std::cout << a;};std::for_each(strVec.begin(), strVec.end(), lambda3);// C++14, 只需要定义一个泛型lambdaauto lambda4 = [](auto a) {std::cout << a;}std::for_each(intVec.begin(), intVec.end(), lambda4);std::for_each(doubleVec.begin(), doubleVec.end(), lambda4);std::for_each(strVec.begin(), strVec.end(), lambda4);}
    
    1. 初始化捕获:
        void Func() {// 在lambda中捕获一个只可移对象std::unique_ptr<int> up1 = std::make_unique<int>(5);// C++11, 十分麻烦// C++14, 使用初始化捕获将up1移入lambda中auto lambda1 = [up2 = std::move(up1)]() {std::cout << *up2;};}
    
  • 建议:
    1. 使用泛型lambda表达式可以简化代码,提高代码复用能力
    2. 捕获列表中使用初始化捕获方式将只可移对象移入lambda中

2.3. 更加宽松的constexpr函数

  • 说明:
    1. C++14中放宽了constexpr函数的函数体不得包含多余一条可执行语句的规定,现在可以有任意多条可执行语句, 可以使用除了goto和try…catch以外的控制语句(if, while, for…)
  • 对比:
        // C++11constexpr int pow(int base, int exp) noexcept {return (exp == 0 ? 1 : base * pow(base, exp - 1));}// C++14constexpr int pow(int base, int exp) noexcept {auto result = 1;for (int i = 0; i < exp; ++i) {result *= base;}return result;}
    
  • 建议:

2.4. 二进制字面值和数字分隔符

  • 说明:
    1. 使用前缀0b后接01数字串,即可创建一个二进制数字
    2. 可以在数字中使用’单引号作为分隔符,提升数字的可读性
  • 对比:
        // 二进制数字// C++98及C++11:无//C++14int val = 0b1101000;    // val的值为104// 数字分隔符int num1 = 1000000000;      // C++98及C++11int num2 = 1'000'000'000;   // C++14int num3 = 1'00000'00'00;   // C++14,分隔符可以任意间隔
    
  • 建议:
    1. 对较大的数字字面值,使用数字分隔符间隔三位隔开,以提升可读性

3. C++17

3.1. 结构化绑定

  • 说明:
    1.结构化绑定 绑定指定名称到初始化器的子对象或元素,其格式为:
        const/static(可选) auto(必选) &/&&(可选) [逗号分隔的标识符列表] = 表达式;const/static(可选) auto(必选) &/&&(可选) [逗号分隔的标识符列表]{表达式};const/static(可选) auto(必选) &/&&(可选) [逗号分隔的标识符列表](表达式);
    
    1. 表达式可以是数组或非union类的任意类型
    2. 表达式是数组类型时:标识符列表中的每个标识符均成为指代数组的对应元素的左值。标识符的数量必须等于数组的元素数量:
        int a[2] = {1,2};auto [x,y] = a; // 创建 e[2],复制 a 到 e,然后 x 指代 e[0],y 指代 e[1]auto& [xr, yr] = a; // xr 指代 a[0],yr 指代 a[1]
    
    1. 表达式是类类型时:标识符列表中的每个标识符绑定到类的各个可访问非静态数据成员:
        struct S {int x1;double y1;};S f();auto [x, y] = f();  // x是x1的拷贝, y是y1的拷贝
    
  • 对比:
    1. std::map的循环遍历
        void Func() {std::map<int, std::string> int2StrMap;...// C++98std::map<int, std::string>::iterator iter = int2StrMap.begin();for (; iter != int2StrMap.end(); ++iter) {std::cout << iter->first << ", " << iter-second;}// C++11for (const auto& pair : int2StrMap) {std::cout << pair.first << ", " << pair.second;}// C++17for (const auto& [val, str] : int2StrMap) {std::cout << val << ", " << str;}}
    
  • 建议:

3.1. 条件分支语句初始化

  • 说明:
    1. C++17中,在if/switch条件语句中可以增加初始化语句:
        if/switch (初始化语句; 条件)// 等价于初始化语句;if/switch (条件)void Func() {std::set<int> intSet;...if (auto it = intSet.find(10); it != intSet.end()) {std::cout << *it;}}
    
  • 对比:
  • 建议:

3.1. std::filesystem

  • 说明:文件系统库
  • 对比:
  • 建议:

3.1. std::string_view

  • 说明:对字符序列或字符串切片的只读非占有引用
  • 对比:
  • 建议:

3.1. std::optional

  • 说明:用于表示可选对象
  • 对比:
  • 建议:

3.1. std::any

  • 说明:用于保存任何类型的单个值
  • 对比:
  • 建议:

3.1. std::variant

  • 说明:带有标记的联合容器
  • 对比:
  • 建议:

参考资料

  1. C++ Primer 5th : C++11大百科全书
  2. Effective Modern C++ : C++11/14的高效用法
  3. http://www.cplusplus.com/ : C++98/11参考手册
  4. https://zh.cppreference.com/w/cpp : C++最新标准参考手册
查看全文
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

相关文章

  1. Linux学习笔记6:文件内容查看与权限

    参考书籍:《鸟哥的Linux私房菜:基础学习篇》 文件内容查看 1、几个常用的查看文件内容的命令: 【cat】由第一行开始显示文件内容 【tac】从最后一行开始显示,tac是cat倒着写 【nl】显示的时候,同时输出行号 【more】一页一页的查看文件内容 【less】与more类似,不过可以往…...

    2024/5/10 5:19:27
  2. 由“需求实现”到“价值引领”:新版如流正在让在线办公蜕变

    文|曾响铃来源|科技向令说(xiangling0815)后疫情时代,在线办公平台挤满了各路玩家,阿里的钉钉、腾讯的企业微信/腾讯会议,百度“如流”(原名百度Hi)悉数登场,加上很多还算优秀的中小明星产品,以三大平台为主、各玩家各有所长的繁荣盛景已经形成。但随着疫情影响的逐步…...

    2024/5/6 6:28:58
  3. [HIT-FLAA]哈工大2020春形式语言与自动机复习笔记 (3)

    文章目录:上下文无关文法和下推自动机1. 上下文无关文法(CFG)1. 上下文无关文法2. 语法分析树3. 二义性4. CFG的化简5. 乔姆斯基范式(CNF)2. 下推自动机(PDA)1. PDA的定义2. 确定的PDA3. PDA的瞬时描述4. PDA接受的语言3. CFG和PDA的等价性1. CFG ⇒\Rightarrow⇒ PDA2. PDA ⇒…...

    2024/5/9 4:21:22
  4. Shell 配置yum源脚本

    Shell 配置yum源脚本 #### 配置yum源脚本 #!/usr/bin/bash ##################################################### # yum config # # v1.0 by malele 2020-4.9 # ########…...

    2024/5/10 4:51:04
  5. 七大Join

    七大join自然连接 select * from a inner join b on a.key = b.key; 左外连接 select * from a left join b on a.key = b.key;右外连接 select * from a right join b on a.key = b.key;a-ab select * from a left join b on a.key = b.key where b.key is null;b-ab select *…...

    2024/4/25 7:55:28
  6. week15_day01_Maven配置&&Junit&&单例、工厂、代理模式

    新阶段的介绍: 课程的情况设计模式(1day)为spring做铺垫 Spring(4days):ioc\di、aop、事务 SpringMVC(4days) Mybatis(4~5days) 持久层框架:用于和mysql数据库做持久化关联的框架,叫持久层框架 持久层就是把数据放在可存储介质中(磁盘) SSM整合(0.5day) Spring Spr…...

    2024/5/9 13:11:57
  7. docker启动mysql后,navicat连接不上mysql的解决方法

    1.docker拉取镜像 docker pull mysql2.运行mysql docker run -p 3308:3306 --name mysql01 -e MYSQL_ROOT_PASSWORD=123456 -d mysql容器名称是:mysql 密码:123456 3.查看运行 docker ps -a4.查看日志 docker logs mysql5.但是使用navicat连接数据时,总是出现错误解决方法1)…...

    2024/5/10 7:08:49
  8. SSM整合(二)------CRUD

    返回JSON数据当客户端向服务器发送请求的时候,服务器处理完请求,要将页面的数据交给客户端时,如果客户端是安卓或者苹果的话,那样解析服务器传来的数据可能就比较麻烦。所以这里采用一个较为常用的解决方案,那就是让服务器将有效的数据以JSON的形式返回给客户端,这样就可…...

    2024/5/6 0:46:24
  9. 华为发布企业服务云化转型战略 未来5年投资5亿美金建设服务能力(2017年09月06日)

    华为发布企业服务云化转型战略 未来5年投资5亿美金建设服务能力2017年09月06日[中国,上海,2017年9月6日] 今日,在HUAWEI CONNECT 2017上,华为面向全球发布企业服务云化转型战略。华为将持续投入云专业服务产品的开发及云平台和云生态的建设,为行业客户提供端到端的云转型服…...

    2024/5/7 16:35:52
  10. java语言概述

    目录软件开发介绍计算机编程语言介绍java语言概述java简史java语言的诞生java语言的主要特性Java 语言运行机制及运行过程java两种核心机制java语言的环境搭建开发体验之HelloWorld常见问题及其解决方法 注释软件开发介绍软件开发软件,即一系列按照特定顺序组织的计算机数据和…...

    2024/5/9 10:06:43
  11. laravel7 LogicException Please make sure the PHP Redis extension is installed and enabled

    首先先确定,laravel redis配置均为正确且redis也已安装的时候还是提示这个错误Please make sure the PHP Redis extension is installed and enabled那么看看一看php redis拓展是不是没打开以我win10 phpstudy为例环境>php>设置拓展组件>把redis打开或者网站>管理…...

    2024/5/7 19:19:42
  12. WPF动态修改控件样式

    首先看一下窗口的xaml文档 <Window x:Class="WpfApp1_test.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft…...

    2024/5/10 4:36:41
  13. 51单片机使用DS18B20

    #include <REG52.H> #include <MYLIB.H>sbit DQ = P3^7; //定义DQ引脚//初始化DS18B20 uchar DS18B20_inint() {uchar i = 0;DQ = 0;delay_10us(50);DQ = 1;while (DQ){delay_10us(1);i++;if(i>5)return 0;}return 1; } //向DS18B20写入一个字节 void DS18B20_w…...

    2024/5/8 9:43:35
  14. 前端基础进阶(十一):详解面向对象、构造函数、原型与原型链

    前端基础进阶(十一):详解面向对象、构造函数、原型与原型链.如果要我总结一下学习前端以来我遇到了哪些瓶颈,那么面向对象一定是第一个会想到的。尽管现在对于面向对象有了一些的了解,但是当初那种似懂非懂的痛苦,依然历历在目。为了帮助大家能够更加直观的学习和了解面向…...

    2024/5/3 17:43:49
  15. Vuex的概念,应用

    vuex快速入门 一、概念 vuex是一个专为vue.js应用程序开发的状态管理模式(它采用集中式存贮管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化)。 二、五大核心属性 核心属性为:state,getter,mutation,action,module state:存储数据,存储状…...

    2024/5/7 19:44:41
  16. SSM整合(三)------CRUD

    批量删除 前端点击右上角删除,可以删除选中的列表项list.js因为添加了选中框,所以重写build_emps_table(result)方法$(function(){//完成全选/全不选功能$("#check_all").click(function () {$(".check_item").prop("checked", $(this).prop(&…...

    2024/4/28 3:43:20
  17. Altium Designer中敷铜间距修改问题

    该问题可以分为两步 (1)修改间距规则,保证敷铜完成 (2)改回原来的间距规则,保证软件不警告...

    2024/4/28 18:38:58
  18. leetcode 110. 平衡二叉树

    题目思路 平衡二叉树:每个节点的左右两个子树的高度差的绝对值不超过 1 如果当前node平衡,则,分别递归判断它的左子树是否平衡,右子树是否平衡。 //测试用例 [1,2,2,3,null,null,3,4,null,null,4] // 答案 false题解 // Definition for a binary tree node. class TreeNode…...

    2024/5/6 17:46:56
  19. 列表

    列表 用下标取得列表中的单个值 假定列表[‘cat’, ‘bat’, ‘rat’, ‘elephant’]保存在名为spam 的变量中。Python 代码spam[0] 将求值为’cat’,spam[1]将求值为’bat’,依此类推。列表后面方括号内的整数被称为“下 标”。列表下标的起始值是0。 如果使用的下标超出了列…...

    2024/5/7 1:54:12
  20. 网络编程

    IP地址IP地址:inet Address唯一定位一台网络上的计算机127.0.0.1:本机local hostipvIP地址的分类:ipv4:127.2.2.1,四个字节组成,0-255,大概有42亿;30亿在北美,亚洲4亿。IPv6: fe80::588c:5b23:d5c5:eed6%13,128位。公网(互联网)——私网(局域网)public class test…...

    2024/5/8 23:48:46

最新文章

  1. 深入解析MySQL中的事务(上)

    MySQL事务管理 一、事务的基本概念为什么需要事务&#xff1f;1. 数据完整性2. 并发控制3. 错误恢复4. 复杂业务逻辑的支持5. 安全性 为什么会出现事务查看引擎是否支持事务事务提交方式自动提交&#xff08;Automatic Commit&#xff09;手动提交&#xff08;Manual Commit&am…...

    2024/5/10 8:36:50
  2. 梯度消失和梯度爆炸的一些处理方法

    在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言&#xff0c;在此感激不尽。 权重和梯度的更新公式如下&#xff1a; w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...

    2024/5/9 21:23:04
  3. Java深度优先搜索DFS(含面试大厂题和源码)

    深度优先搜索&#xff08;Depth-First Search&#xff0c;简称DFS&#xff09;是一种用于遍历或搜索树或图的算法。DFS 通过沿着树的深度来遍历节点&#xff0c;尽可能深地搜索树的分支。当节点v的所在边都已被探寻过&#xff0c;搜索将回溯到发现节点v的那条边的起始节点。这个…...

    2024/5/10 0:59:45
  4. 利用Spark将Kafka数据流写入HDFS

    利用Spark将Kafka数据流写入HDFS 在当今的大数据时代&#xff0c;实时数据处理和分析变得越来越重要。Apache Kafka作为一个分布式流处理平台&#xff0c;已经成为处理实时数据的事实标准。而Apache Spark则是一个强大的大数据处理框架&#xff0c;它提供了对数据进行复杂处理…...

    2024/5/10 0:08:22
  5. 416. 分割等和子集问题(动态规划)

    题目 题解 class Solution:def canPartition(self, nums: List[int]) -> bool:# badcaseif not nums:return True# 不能被2整除if sum(nums) % 2 ! 0:return False# 状态定义&#xff1a;dp[i][j]表示当背包容量为j&#xff0c;用前i个物品是否正好可以将背包填满&#xff…...

    2024/5/10 1:36:26
  6. 【Java】ExcelWriter自适应宽度工具类(支持中文)

    工具类 import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet;/*** Excel工具类** author xiaoming* date 2023/11/17 10:40*/ public class ExcelUti…...

    2024/5/9 7:40:42
  7. Spring cloud负载均衡@LoadBalanced LoadBalancerClient

    LoadBalance vs Ribbon 由于Spring cloud2020之后移除了Ribbon&#xff0c;直接使用Spring Cloud LoadBalancer作为客户端负载均衡组件&#xff0c;我们讨论Spring负载均衡以Spring Cloud2020之后版本为主&#xff0c;学习Spring Cloud LoadBalance&#xff0c;暂不讨论Ribbon…...

    2024/5/9 2:44:26
  8. TSINGSEE青犀AI智能分析+视频监控工业园区周界安全防范方案

    一、背景需求分析 在工业产业园、化工园或生产制造园区中&#xff0c;周界防范意义重大&#xff0c;对园区的安全起到重要的作用。常规的安防方式是采用人员巡查&#xff0c;人力投入成本大而且效率低。周界一旦被破坏或入侵&#xff0c;会影响园区人员和资产安全&#xff0c;…...

    2024/5/10 2:07:45
  9. VB.net WebBrowser网页元素抓取分析方法

    在用WebBrowser编程实现网页操作自动化时&#xff0c;常要分析网页Html&#xff0c;例如网页在加载数据时&#xff0c;常会显示“系统处理中&#xff0c;请稍候..”&#xff0c;我们需要在数据加载完成后才能继续下一步操作&#xff0c;如何抓取这个信息的网页html元素变化&…...

    2024/5/10 8:07:24
  10. 【Objective-C】Objective-C汇总

    方法定义 参考&#xff1a;https://www.yiibai.com/objective_c/objective_c_functions.html Objective-C编程语言中方法定义的一般形式如下 - (return_type) method_name:( argumentType1 )argumentName1 joiningArgument2:( argumentType2 )argumentName2 ... joiningArgu…...

    2024/5/9 5:40:03
  11. 【洛谷算法题】P5713-洛谷团队系统【入门2分支结构】

    &#x1f468;‍&#x1f4bb;博客主页&#xff1a;花无缺 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 花无缺 原创 收录于专栏 【洛谷算法题】 文章目录 【洛谷算法题】P5713-洛谷团队系统【入门2分支结构】&#x1f30f;题目描述&#x1f30f;输入格…...

    2024/5/10 8:16:30
  12. 【ES6.0】- 扩展运算符(...)

    【ES6.0】- 扩展运算符... 文章目录 【ES6.0】- 扩展运算符...一、概述二、拷贝数组对象三、合并操作四、参数传递五、数组去重六、字符串转字符数组七、NodeList转数组八、解构变量九、打印日志十、总结 一、概述 **扩展运算符(...)**允许一个表达式在期望多个参数&#xff0…...

    2024/5/10 2:07:43
  13. 摩根看好的前智能硬件头部品牌双11交易数据极度异常!——是模式创新还是饮鸩止渴?

    文 | 螳螂观察 作者 | 李燃 双11狂欢已落下帷幕&#xff0c;各大品牌纷纷晒出优异的成绩单&#xff0c;摩根士丹利投资的智能硬件头部品牌凯迪仕也不例外。然而有爆料称&#xff0c;在自媒体平台发布霸榜各大榜单喜讯的凯迪仕智能锁&#xff0c;多个平台数据都表现出极度异常…...

    2024/5/10 2:07:43
  14. Go语言常用命令详解(二)

    文章目录 前言常用命令go bug示例参数说明 go doc示例参数说明 go env示例 go fix示例 go fmt示例 go generate示例 总结写在最后 前言 接着上一篇继续介绍Go语言的常用命令 常用命令 以下是一些常用的Go命令&#xff0c;这些命令可以帮助您在Go开发中进行编译、测试、运行和…...

    2024/5/9 4:12:16
  15. 用欧拉路径判断图同构推出reverse合法性:1116T4

    http://cplusoj.com/d/senior/p/SS231116D 假设我们要把 a a a 变成 b b b&#xff0c;我们在 a i a_i ai​ 和 a i 1 a_{i1} ai1​ 之间连边&#xff0c; b b b 同理&#xff0c;则 a a a 能变成 b b b 的充要条件是两图 A , B A,B A,B 同构。 必要性显然&#xff0…...

    2024/5/9 7:40:35
  16. 【NGINX--1】基础知识

    1、在 Debian/Ubuntu 上安装 NGINX 在 Debian 或 Ubuntu 机器上安装 NGINX 开源版。 更新已配置源的软件包信息&#xff0c;并安装一些有助于配置官方 NGINX 软件包仓库的软件包&#xff1a; apt-get update apt install -y curl gnupg2 ca-certificates lsb-release debian-…...

    2024/5/9 19:47:07
  17. Hive默认分割符、存储格式与数据压缩

    目录 1、Hive默认分割符2、Hive存储格式3、Hive数据压缩 1、Hive默认分割符 Hive创建表时指定的行受限&#xff08;ROW FORMAT&#xff09;配置标准HQL为&#xff1a; ... ROW FORMAT DELIMITED FIELDS TERMINATED BY \u0001 COLLECTION ITEMS TERMINATED BY , MAP KEYS TERMI…...

    2024/5/9 7:40:34
  18. 【论文阅读】MAG:一种用于航天器遥测数据中有效异常检测的新方法

    文章目录 摘要1 引言2 问题描述3 拟议框架4 所提出方法的细节A.数据预处理B.变量相关分析C.MAG模型D.异常分数 5 实验A.数据集和性能指标B.实验设置与平台C.结果和比较 6 结论 摘要 异常检测是保证航天器稳定性的关键。在航天器运行过程中&#xff0c;传感器和控制器产生大量周…...

    2024/5/10 2:07:41
  19. --max-old-space-size=8192报错

    vue项目运行时&#xff0c;如果经常运行慢&#xff0c;崩溃停止服务&#xff0c;报如下错误 FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory 因为在 Node 中&#xff0c;通过JavaScript使用内存时只能使用部分内存&#xff08;64位系统&…...

    2024/5/9 5:02:59
  20. 基于深度学习的恶意软件检测

    恶意软件是指恶意软件犯罪者用来感染个人计算机或整个组织的网络的软件。 它利用目标系统漏洞&#xff0c;例如可以被劫持的合法软件&#xff08;例如浏览器或 Web 应用程序插件&#xff09;中的错误。 恶意软件渗透可能会造成灾难性的后果&#xff0c;包括数据被盗、勒索或网…...

    2024/5/9 4:31:45
  21. JS原型对象prototype

    让我简单的为大家介绍一下原型对象prototype吧&#xff01; 使用原型实现方法共享 1.构造函数通过原型分配的函数是所有对象所 共享的。 2.JavaScript 规定&#xff0c;每一个构造函数都有一个 prototype 属性&#xff0c;指向另一个对象&#xff0c;所以我们也称为原型对象…...

    2024/5/9 16:54:42
  22. C++中只能有一个实例的单例类

    C中只能有一个实例的单例类 前面讨论的 President 类很不错&#xff0c;但存在一个缺陷&#xff1a;无法禁止通过实例化多个对象来创建多名总统&#xff1a; President One, Two, Three; 由于复制构造函数是私有的&#xff0c;其中每个对象都是不可复制的&#xff0c;但您的目…...

    2024/5/10 1:31:37
  23. python django 小程序图书借阅源码

    开发工具&#xff1a; PyCharm&#xff0c;mysql5.7&#xff0c;微信开发者工具 技术说明&#xff1a; python django html 小程序 功能介绍&#xff1a; 用户端&#xff1a; 登录注册&#xff08;含授权登录&#xff09; 首页显示搜索图书&#xff0c;轮播图&#xff0…...

    2024/5/9 6:36:49
  24. 电子学会C/C++编程等级考试2022年03月(一级)真题解析

    C/C++等级考试(1~8级)全部真题・点这里 第1题:双精度浮点数的输入输出 输入一个双精度浮点数,保留8位小数,输出这个浮点数。 时间限制:1000 内存限制:65536输入 只有一行,一个双精度浮点数。输出 一行,保留8位小数的浮点数。样例输入 3.1415926535798932样例输出 3.1…...

    2024/5/9 4:33:29
  25. 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...

    解析如下&#xff1a;1、长按电脑电源键直至关机&#xff0c;然后再按一次电源健重启电脑&#xff0c;按F8健进入安全模式2、安全模式下进入Windows系统桌面后&#xff0c;按住“winR”打开运行窗口&#xff0c;输入“services.msc”打开服务设置3、在服务界面&#xff0c;选中…...

    2022/11/19 21:17:18
  26. 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。

    %读入6幅图像&#xff08;每一幅图像的大小是564*564&#xff09; f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...

    2022/11/19 21:17:16
  27. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

    win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面&#xff0c;在等待界面中我们需要等待操作结束才能关机&#xff0c;虽然这比较麻烦&#xff0c;但是对系统进行配置和升级…...

    2022/11/19 21:17:15
  28. 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...

    有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows&#xff0c;请勿关闭计算机”的提示&#xff0c;要过很久才能进入系统&#xff0c;有的用户甚至几个小时也无法进入&#xff0c;下面就教大家这个问题的解决方法。第一种方法&#xff1a;我们首先在左下角的“开始…...

    2022/11/19 21:17:14
  29. win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...

    置信有很多用户都跟小编一样遇到过这样的问题&#xff0c;电脑时发现开机屏幕显现“正在配置Windows Update&#xff0c;请勿关机”(如下图所示)&#xff0c;而且还需求等大约5分钟才干进入系统。这是怎样回事呢&#xff1f;一切都是正常操作的&#xff0c;为什么开时机呈现“正…...

    2022/11/19 21:17:13
  30. 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...

    Win7系统开机启动时总是出现“配置Windows请勿关机”的提示&#xff0c;没过几秒后电脑自动重启&#xff0c;每次开机都这样无法进入系统&#xff0c;此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一&#xff1a;开机按下F8&#xff0c;在出现的Windows高级启动选…...

    2022/11/19 21:17:12
  31. 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...

    有不少windows10系统用户反映说碰到这样一个情况&#xff0c;就是电脑提示正在准备windows请勿关闭计算机&#xff0c;碰到这样的问题该怎么解决呢&#xff0c;现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法&#xff1a;1、2、依次…...

    2022/11/19 21:17:11
  32. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...

    今天和大家分享一下win7系统重装了Win7旗舰版系统后&#xff0c;每次关机的时候桌面上都会显示一个“配置Windows Update的界面&#xff0c;提示请勿关闭计算机”&#xff0c;每次停留好几分钟才能正常关机&#xff0c;导致什么情况引起的呢&#xff1f;出现配置Windows Update…...

    2022/11/19 21:17:10
  33. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...

    只能是等着&#xff0c;别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚&#xff0c;只能是考虑备份数据后重装系统了。解决来方案一&#xff1a;管理员运行cmd&#xff1a;net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...

    2022/11/19 21:17:09
  34. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

    原标题&#xff1a;电脑提示“配置Windows Update请勿关闭计算机”怎么办&#xff1f;win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢&#xff1f;一般的方…...

    2022/11/19 21:17:08
  35. 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...

    关机提示 windows7 正在配置windows 请勿关闭计算机 &#xff0c;然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;关机提示 windows7 正在配…...

    2022/11/19 21:17:05
  36. 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...

    钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...

    2022/11/19 21:17:05
  37. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...

    前几天班里有位学生电脑(windows 7系统)出问题了&#xff0c;具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面&#xff0c;长时间没反应&#xff0c;无法进入系统。这个问题原来帮其他同学也解决过&#xff0c;网上搜了不少资料&#x…...

    2022/11/19 21:17:04
  38. 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...

    本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法&#xff0c;并在最后教给你1种保护系统安全的好方法&#xff0c;一起来看看&#xff01;电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中&#xff0c;添加了1个新功能在“磁…...

    2022/11/19 21:17:03
  39. 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...

    许多用户在长期不使用电脑的时候&#xff0c;开启电脑发现电脑显示&#xff1a;配置windows更新失败&#xff0c;正在还原更改&#xff0c;请勿关闭计算机。。.这要怎么办呢&#xff1f;下面小编就带着大家一起看看吧&#xff01;如果能够正常进入系统&#xff0c;建议您暂时移…...

    2022/11/19 21:17:02
  40. 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...

    配置windows update失败 还原更改 请勿关闭计算机&#xff0c;电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;配置windows update失败 还原更改 请勿关闭计算机&#x…...

    2022/11/19 21:17:01
  41. 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...

    不知道大家有没有遇到过这样的一个问题&#xff0c;就是我们的win7系统在关机的时候&#xff0c;总是喜欢显示“准备配置windows&#xff0c;请勿关机”这样的一个页面&#xff0c;没有什么大碍&#xff0c;但是如果一直等着的话就要两个小时甚至更久都关不了机&#xff0c;非常…...

    2022/11/19 21:17:00
  42. 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...

    当电脑出现正在准备配置windows请勿关闭计算机时&#xff0c;一般是您正对windows进行升级&#xff0c;但是这个要是长时间没有反应&#xff0c;我们不能再傻等下去了。可能是电脑出了别的问题了&#xff0c;来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...

    2022/11/19 21:16:59
  43. 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...

    我们使用电脑的过程中有时会遇到这种情况&#xff0c;当我们打开电脑之后&#xff0c;发现一直停留在一个界面&#xff1a;“配置Windows Update失败&#xff0c;还原更改请勿关闭计算机”&#xff0c;等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢&#xff0…...

    2022/11/19 21:16:58
  44. 如何在iPhone上关闭“请勿打扰”

    Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...

    2022/11/19 21:16:57