C++11中跳转initializer_list实现分析

C++11中跳转initializer_list实现分析

简介

在 C++11 标准之前,C++ 中只有 C 风格的可变参数传递,而在 C++11 中加入了新的 initializer_list 类型,从而实现了更加方便和安全的可变参数列表传递。
initializer_list 可以看作是一个轻量级的容器,只能存放相同类型的变量,支持动态数组大小的初始化,并且可以像数组或标准容器一样进行迭代访问。

initializer_list 的定义和用法

定义

initializer_list 类型定义在头文件 <initializer_list> 中,其定义如下:

namespace std {
    template<class T>
    class initializer_list {
    public:
        using value_type      = T;
        using reference       = const T&;
        using const_reference = const T&;
        using size_type       = size_t;

        using iterator        = const T*;
        using const_iterator  = const T*;

        constexpr initializer_list() noexcept;
        constexpr size_t size() const noexcept;
        constexpr const T* begin() const noexcept;
        constexpr const T* end() const noexcept;
    };
    . . . . .
}

用法

使用 initializer_list 的一般方法是利用其构造函数进行初始化,然后像使用容器一样访问其中的元素:

#include <iostream>
#include <initializer_list>

int main()
{
    std::initializer_list<int> list = { 1, 2, 3 };
    for (auto i : list) {
        std::cout << i << std::endl;
    }
    return 0;
}

输出结果:

1
2
3

跳转 initializer_list 的实现

C++11 新增了跳转语句 return expr;,其中 expr 是一个 initializer_list,用于在函数内跳转到该语句处并返回一组指定的值。
使用跳转语句可以实现 initializer_list 的传递,具体实现方法如下:

#include <iostream>
#include <initializer_list>

// 接收可变参数列表的函数
void function(std::initializer_list<int> list)
{
    for (auto i : list) { // 遍历数组
        std::cout << i << std::endl; // 打印
    }
}

// 返回可变参数列表的函数
std::initializer_list<int> get_list()
{
    std::initializer_list<int> list = { 1, 2, 3 };
    return list; // 返回数组
}

int main()
{
    // 调用函数传递可变参数列表
    function({1, 2, 3});

    // 调用函数返回可变参数列表
    std::initializer_list<int> list = get_list();
    for (auto i : list) { // 遍历数组
        std::cout << i << std::endl; // 打印
    }

    return 0;
}

输出结果:

1
2
3
1
2
3

以上示例说明了在函数参数中使用 initializer_list 和函数返回值中使用 initializer_list 的使用方式。其中 function 函数使用了可变参数列表作为函数参数,在函数内部遍历多个参数,而 get_list 函数返回了一个 initializer_list,其内部有三个元素。函数调用时,在花括号中传入实际参数,然后在函数体中实现遍历或其他操作。

示例

示例1:简单的可变参数宏

在实际编码过程中,我们往往会使用可变参数宏,它可以接受可变的参数并进行处理。下面是一个简单的示例:

#include <iostream>

#define DEBUG_PRINT(...) std::cout << #__VA_ARGS__ << " = " << (__VA_ARGS__) << std::endl;

int main()
{
    int a = 1, b = 2, c = 3;
    DEBUG_PRINT(a, b, c); // 使用可变参数宏打印变量值
    return 0;
}

输出结果:

a, b, c = 1 2 3

示例 2:结合 stl 算法的使用

我们也可以结合 STL 算法对可变参数列表进行处理。例如在下面的代码中,我们定义了一个 container 容器,然后使用 find 算法遍历该容器,查找元素是否在容器内。其中可以注意到,我们在算法的第一个参数中使用了可变参数列表。

#include <algorithm>
#include <iostream>
#include <vector>

template <typename ... Args>
bool find_in_container(const std::vector<int>& container, Args&&... args)
{
  return std::find(container.begin(), container.end(), std::forward<Args>(args)) != container.end();
}

int main()
{
    std::vector<int> container = { 1, 2, 3, 4, 5 };
    std::cout << std::boolalpha;

    // 查找容器中的元素
    std::cout << find_in_container(container, 3, 4, 5) << std::endl; // 输出 true
    std::cout << find_in_container(container, 6, 7, 8) << std::endl; // 输出 false

    return 0;
}

输出结果:

true
false

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++11中跳转initializer_list实现分析 - Python技术站

(0)
上一篇 2023年5月23日
下一篇 2023年5月23日

相关文章

  • C++11的for循环,以及范围Range类的简单实现

    C++11的for循环和范围(Range)类是在C++11标准中引入的新特性。C++11的for循环允许我们使用更加简洁的语法来遍历数组、容器、等其他可迭代的对象,而范围(Range)类则提供了一种更加直观、可读性更好的方法来表示一个对象的范围。 C++11的for循环 使用C++11的for循环,可以通过以下简洁的语法来遍历数组: int arr[] = …

    C 2023年5月22日
    00
  • 荣耀畅玩7c怎么打开游戏模式?荣耀畅玩7c打开游戏模式教程

    下面是荣耀畅玩7c打开游戏模式的完整攻略,包含了详细的步骤以及示例说明。 什么是游戏模式 游戏模式是一种手机功能,它能够优化手机性能,使得手机在运行游戏时更加流畅。荣耀畅玩7c也拥有游戏模式功能,用户可以通过打开游戏模式来获得更好的游戏体验。 如何打开游戏模式 荣耀畅玩7c打开游戏模式的步骤如下: 进入手机“设置”界面。 找到并点击“智能辅助”选项。 找到并…

    C 2023年5月23日
    00
  • C程序 Hello World

    下面就为大家详细讲解一下C程序 HelloWorld的完整使用攻略。 1. 创建C程序 首先,我们需要在本地电脑上安装C语言编译器。常用的编译器有GCC、Clang等,其中GCC是最为常见的一个编译器。 在Windows上安装GCC编译器 下载MinGW安装包(http://www.mingw.org/),并按照提示安装。 将MinGW的bin目录加入到系统…

    C 2023年5月9日
    00
  • C#多线程异步执行和跨线程访问控件Helper

    关于C#多线程异步执行和跨线程访问控件Helper,我会分为以下几个部分进行讲解: 什么是多线程异步执行和跨线程访问控件 为什么需要多线程异步执行和跨线程访问控件 实现多线程异步执行和跨线程访问控件的方法 示例说明:多线程异步执行 示例说明:跨线程访问控件Helper 什么是多线程异步执行和跨线程访问控件 多线程异步执行是指在执行过程中,可以有多个线程同时进…

    C 2023年5月22日
    00
  • C++ 通过pqxxlib库链接 PostgreSql数据库的详细过程

    C++ 是广泛使用的编程语言之一,与后端的数据库管理息息相关。其中,PostgreSQL 是一个功能齐全的开源对象-关系数据库管理系统,被广泛应用于 Web 应用程序的数据存储。在 C++ 中,通过使用 pqxxlib 库的链接,可以很方便地访问并操作 PostgreSQL 数据库。 下面是 C++ 通过 pqxxlib 库链接 PostgreSQL 数据库…

    C 2023年5月22日
    00
  • c调用python调试方法

    下面是我为您提供的“C调用Python调试方法”的完整攻略。 1. 准备工作 在开始调试之前,您需要确认您已经完成以下准备工作: 安装 Python 解释器和相应的依赖库。 编写 Python 脚本并进行相关测试,确保 Python 脚本可用。 编写 C 代码,并根据您的需求将其与 Python 脚本进行交互。在 C 代码中,您可以使用 Python 提供的…

    C 2023年5月23日
    00
  • C语言 图文并茂详解程序编译过程

    C语言 图文并茂详解程序编译过程 编译器是将我们编写的源代码转化成执行文件的工具。在C语言中,利用编译器可以将代码编译成目标代码,并链接到可执行文件中。下面是程序编译的详细过程。 程序编译的各个阶段 1. 预处理阶段 预处理器会进行一些特定的替换和指令扩展,例如#include指令将头文件添加到源代码文件中,宏定义将对代码中使用宏的地方进行替换。预处理器会生…

    C 2023年5月23日
    00
  • MySQL中查询json格式的字段实例详解

    MySQL中查询json格式的字段需要使用JSON函数。此处介绍几个常用的MySQL JSON函数。 JSON_EXTRACT JSON_EXTRACT可以用来提取json中的某个值,其语法如下: JSON_EXTRACT(json_obj, path) 其中,json_obj表示json对象,path表示要提取的值的路径。路径可以是简单的key或者是嵌套的…

    C 2023年5月23日
    00
合作推广
合作推广
分享本页
返回顶部