【C++复习】C++11经典语法

文章目录

  • {}列表初始化
      • 1. 初始化内置类型变量
      • 2. 初始化数组
      • 3. 初始化标准容器
      • 4. 初始化自定义类型
      • 5. 构造函数初始化列表
      • 6. 初始化列表(initializer_list)
      • 7. 返回值初始化
      • 8. 静态成员变量和全局变量的就地初始化
      • 9. 防止类型收窄
      • 总结
  • decltype
  • 右值引用
  • 完美转发--由右值引用引发的问题
  • delete default
  • 逗号表达式
      • 特性
      • 示例
      • 注意事项
  • 可变参数模板
    • 展开参数包
  • emplace_back
  • 仿函数
  • function包装器/适配器/类模板
  • bind函数模板/包装器/适配器

{}列表初始化

1. 初始化内置类型变量

  • 直接初始化int a{10};。明确表达初始化过程,避免与赋值混淆。
  • 空列表初始化:如果{}内为空,则内置类型变量会被初始化为该类型的零值,如int b{};会将b初始化为0

2. 初始化数组

  • C++98风格:在C++98中,数组初始化就需要使用{},如int arr1[] = {1, 2, 3};
  • C++11风格:C++11引入了更简洁的数组初始化方式,允许省略=,如int arr2[]{1, 2, 3};

3. 初始化标准容器

  • STL容器:如vectormap等,可以使用{}进行初始化,

    vector<int> v{
         1, 2, 3};
    map<int, float> m{
          {
         1, 1.0f}, {
         2, 2.0f} };
    

4. 初始化自定义类型

  • 无模板类:对于自定义的无模板类,可以在构造函数中使用{}初始化成员变量,也可以在对象创建时直接使用{}进行初始化,如struct A { A(int a = 0, int b = 0) : _a(a), _b(b) {} }; A a{1, 2};
  • 模板类:模板类同样支持使用{}进行初始化,如template struct B { B(T c = 0, T d = 0) : _c(c), _d(d) {} }; B b{3, 4};

5. 构造函数初始化列表

  • 在类的构造函数中,可以使用{}来初始化成员变量,这有助于确保成员变量在构造函数体执行之前就被正确初始化。

6. 初始化列表(initializer_list)

  • C++11引入了initializer_list,允许构造函数接收一个初始化列表作为参数,从而可以更方便地初始化容器或自定义类型。
  • 示例:class C { C(initializer_list lt) : _arr(lt) {} private: vector _arr; }; C c = {1, 2, 3, 4};

7. 返回值初始化

  • 在函数返回时,也可以使用{}来初始化返回值,这有助于确保返回值的正确性和类型安全。

8. 静态成员变量和全局变量的就地初始化

  • 在C++11中,除了构造函数初始化列表外,还允许使用={}对静态成员变量和全局变量进行就地初始化。

9. 防止类型收窄

  • 列表初始化可以防止类型收窄,即当尝试将一种类型的值初始化为另一种类型(且这种转换可能会导致精度损失或范围超出)时,编译器会报错。

总结

int a{
   10}; //明确表达初始化过程,避免与赋值混淆
int b{
   }; //空列表初始化 内置类型变量会被初始化为该类型的零值

int arr1[] = {
   1, 2, 3};
int arr2[]{
   1, 2, 3};

int* pa = new int[4]{
    1,2,3,4 };

vector<int> v{
   1, 2, 3};
map<int, float> m{
    {
   1, 1.0f}, {
   2, 2.0f} };

struct A 
{
    
    A(int a = 0, int b = 0) : _a(a), _b(b) 
    {
   

    } 
}; 
A a{
   1, 2};

template<class T> 
struct B 
{
    
    B(T c = 0, T d = 0) : _c(c), _d(d) 
    {
   
        
    } 
}; 
B<int> b{
   3, 4};

class C 
{
    
    C(initializer_list<int> lt) : _arr(lt) 
    {
   
        
    } 
private: 
    vector<int> _arr; 
}; 
C c = {
   1, 2, 3, 4};

std::string createString() 
{
     
    return {
   "Hello, World!"}; // 使用 {} 初始化返回值  
}

static int staticVar = 42; // 使用 = 初始化  
static std::string staticStringVar{
   "Static String"}; // 使用 {} 初始化  
  
int globalVar = 100; // 使用 = 初始化  
std::string globalStringVar{
   "Global String"}; // 使用 {} 初始化  

char c1 = 256; // 可能不会报错,但值会被截断  
// char c2{256}; // 这会编译错误,因为256超出了char的表示范围  
  
// 尝试将浮点数转换为整数,同样使用 {} 可以防止类型收窄  
float f = 3.14;  
int i1 = f; // 隐式转换,f的值被截断为整数  
// int i2{f}; // 这会编译错误,因为浮点数到整数的转换可能不安全  
int i3 = static_cast<int>(f); // 显式转换,明确意图 // 安全的转换  

int main()
{
   
    auto i = {
    10,20,30 };
    cout << typeid(i).name() << endl; // class std::initializer list

    return 0;
}


int 

你可能感兴趣的:(#,C++复习,c++,开发语言,C++11)