c++11新特性

简介: c++11新特性

Variadic TempLates(数量不定的模板参数): ...(可以很方便的完成函数递归调用)

...就是一个所谓的pack;

用于模板参数,就是模板参数包;

用于函数参数类型,就是函数参数类型包;

用于函数参数,就是函数参数包。

注意:要特别处理承参数为0个的情况

sizeof...(args):参数个数

void print(){
}
template <typename T, typename...Types>
void print(const T& firstArg,const Types&... args){
}

模板表达式中的空格:

c++11后空格有无都无所谓,c++11前必须要有。

nullptr和std::nullptr_t:

c++11允许使用nullptr替代0或者NULL作为无值指针的结果,这种新特性避免了null指针被解释为整形值的错误发生。

nullptr是一个关键字,包含了nullptr_t.

auto:

c++11中允许使用auto声明一个不用指出具体类型的变量或者对象,编译器自己会做实参推导,在类型特别长和复杂的时候特别有用,简单类型的不建议用,因为耗时较长。

一致性初始化:

C++11引入了一致性初始化(Uniform Initialization)的新特性,这个特性允许你使用一种统一的语法来初始化各种不同类型的变量,包括基本数据类型、类对象、数组等。一致性初始化的目标是简化和统一初始化的语法,提高代码的可读性和可维护性。

  • 使用大括号 {} 进行初始化:
int x{42};            // 初始化整数
std::string name{"John"};  // 初始化字符串
std::vector<int> numbers{1, 2, 3};  // 初始化容器
int i{};//初始化为0
int* q{};//初始化为nullptr;
  • 使用圆括号 () 进行初始化:
int y(24);                // 使用圆括号初始化整数
std::vector<double> data(10, 0.0);  // 使用圆括号初始化容器
  • 使用等号 = 进行初始化:
int z = 17;               // 使用等号初始化整数
double pi = 3.14159;      // 使用等号初始化浮点数

initializer_list:

C++中的initializer_list是一个用于传递初始化值列表的特性,它在C++11引入,并被广泛用于初始化容器、自定义类的对象和其他支持初始化列表的场合。initializer_list允许你以一种类似于数组的方式传递一组值,并可以在接收这些值的函数或构造函数中使用。以下是initializer_list的主要特性和用法:

  • 完整代码样例:
#include<iostream>
class MyVector {
public:
    MyVector(std::initializer_list<int> values) {
        data_ = new int[values.size()];
        size_ = values.size();
        int i = 0;
        for (int num : values) {
            data_[i++] = num;
        }
    }
    void show(){
        for(int i = 0 ;i<size_;++i){
            std::cout<<data_[i]<<", ";
        }
        std::cout<<std::endl;
    }
    // 其他成员函数...
private:
    int* data_;
    size_t size_;
};
void printNumbers(std::initializer_list<int> numbers) {
    for (int num : numbers) {
        std::cout << num << " ";
    }
    std::cout << std::endl;
}
int main(){
    std::cout<<"hello world"<<std::endl;
    std::initializer_list<int> numbers = {1, 2, 3, 4, 5};
    std::cout << std::endl;
// 调用函数并传递初始化列表
printNumbers({1,2,3,4});
for (int num : {1, 2, 3, 4, 5}) {
    std::cout << num << " ";
}
std::cout << std::endl;
// 使用initializer_list来创建MyVector对象
MyVector vec = {1, 2, 3, 4, 5};
vec.show();
}
  • 初始化列表的语法:

使用大括号 {} 包围一组值,逗号分隔这些值,创建一个initializer_list对象。

std::initializer_list<int> numbers = {1, 2, 3, 4, 5};
  • 用途:
  1. 传递不定数量的参数给函数。
  2. 初始化STL容器,如std::vectorstd::initializer_list等。
  3. 自定义类的构造函数参数,用于初始化对象的成员。
  4. 使用范围for循环遍历初始化列表中的元素
  • 传值给函数:

initializer_list常常用于传递一组值给函数,允许函数接收不定数量的参数。例如

void printNumbers(std::initializer_list<int> numbers) {
    for (int num : numbers) {
        std::cout << num << " ";
    }
    std::cout << std::endl;
}
// 调用函数并传递初始化列表
printNumbers({1, 2, 3, 4, 5});
  • 使用for循环

initializer_list通常与范围for循环一起使用,以便轻松地遍历其中的元素。

for (int num : {1, 2, 3, 4, 5}) {
    std::cout << num << " ";
}
std::cout << std::endl;
  • 自定义类型构造函数参数

可以在自定义类中使用initializer_list构造函数来接收初始化列表,并以其为对象的成员进行初始化。

#include<iostream>
class MyVector {
public:
    MyVector(std::initializer_list<int> values) {
        data_ = new int[values.size()];
        size_ = values.size();
        int i = 0;
        for (int num : values) {
            data_[i++] = num;
        }
    }
    void show(){
        for(int i = 0 ;i<size_;++i){
            std::cout<<data_[i]<<", ";
        }
        std::cout<<std::endl;
    }
    // 其他成员函数...
private:
    int* data_;
    size_t size_;
};
void printNumbers(std::initializer_list<int> numbers) {
    for (int num : numbers) {
        std::cout << num << " ";
    }
    std::cout << std::endl;
}
int main(){
    std::cout<<"hello world"<<std::endl;
    std::initializer_list<int> numbers = {1, 2, 3, 4, 5};
    std::cout << std::endl;
// 调用函数并传递初始化列表
printNumbers({1,2,3,4});
for (int num : {1, 2, 3, 4, 5}) {
    std::cout << num << " ";
}
std::cout << std::endl;
// 使用initializer_list来创建MyVector对象
MyVector vec = {1, 2, 3, 4, 5};
vec.show();
}


相关文章
|
1月前
|
编译器 程序员 定位技术
C++ 20新特性之Concepts
在C++ 20之前,我们在编写泛型代码时,模板参数的约束往往通过复杂的SFINAE(Substitution Failure Is Not An Error)策略或繁琐的Traits类来实现。这不仅难以阅读,也非常容易出错,导致很多程序员在提及泛型编程时,总是心有余悸、脊背发凉。 在没有引入Concepts之前,我们只能依靠经验和技巧来解读编译器给出的错误信息,很容易陷入“类型迷路”。这就好比在没有GPS导航的年代,我们依靠复杂的地图和模糊的方向指示去一个陌生的地点,很容易迷路。而Concepts的引入,就像是给C++的模板系统安装了一个GPS导航仪
102 59
|
1月前
|
存储 编译器 C++
【C++】面向对象编程的三大特性:深入解析多态机制(三)
【C++】面向对象编程的三大特性:深入解析多态机制
|
1月前
|
存储 编译器 C++
【C++】面向对象编程的三大特性:深入解析多态机制(二)
【C++】面向对象编程的三大特性:深入解析多态机制
|
1月前
|
编译器 C++
【C++】面向对象编程的三大特性:深入解析多态机制(一)
【C++】面向对象编程的三大特性:深入解析多态机制
|
1月前
|
存储 安全 编译器
【C++】C++特性揭秘:引用与内联函数 | auto关键字与for循环 | 指针空值(一)
【C++】C++特性揭秘:引用与内联函数 | auto关键字与for循环 | 指针空值
|
24天前
|
C++
C++ 20新特性之结构化绑定
在C++ 20出现之前,当我们需要访问一个结构体或类的多个成员时,通常使用.或->操作符。对于复杂的数据结构,这种访问方式往往会显得冗长,也难以理解。C++ 20中引入的结构化绑定允许我们直接从一个聚合类型(比如:tuple、struct、class等)中提取出多个成员,并为它们分别命名。这一特性大大简化了对复杂数据结构的访问方式,使代码更加清晰、易读。
31 0
|
2月前
|
编译器 C++ 计算机视觉
C++ 11新特性之完美转发
C++ 11新特性之完美转发
47 4
|
2月前
|
Java C# C++
C++ 11新特性之语法甜点1
C++ 11新特性之语法甜点1
31 4
|
2月前
|
安全 程序员 编译器
C++ 11新特性之auto和decltype
C++ 11新特性之auto和decltype
38 3
|
2月前
|
设计模式 缓存 安全
C++ 11新特性之week_ptr
C++ 11新特性之week_ptr
33 2