C++遍历std::tuple(C++14 ~ C++20)

这篇具有很好参考价值的文章主要介绍了C++遍历std::tuple(C++14 ~ C++20)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本文展示了遍历std::tuple的方式:

首先比较容易想到的是利用C++14的std::make_index_sequencestd::get结合取值,然后配合std::initializer_list进行包展开:

// since C++14
class Func0 {
    template<typename T, typename F, size_t... I>
    void init(T&& t, F&& f, std::index_sequence<I...>) {
        std::initializer_list<int>{ (f(std::get<I>(t)), 0)... };
    }
public:
    template<typename T, typename F>
    auto operator()(T&& t, F&& f) {
        init(t, f, std::make_index_sequence<std::tuple_size_v<std::remove_reference_t<T>>>{});
    }
};

到了C++17,我们有了折叠表达式(Fold expressions),就可以直白一点了:

// since C++17
class Func1 {
    template<typename T, typename F, size_t... I>
    void init(T&& t, F&& f, std::index_sequence<I...>) {
        ((f(std::get<I>(t))), ...);
    }
public:
    template<typename T, typename F>
    auto operator()(T&& t, F&& f) {
        init(t, f, std::make_index_sequence<std::tuple_size_v<std::remove_reference_t<T>>>{});
    }
};

C++20允许lambda添加模板参数,因此我们可以进一步限制这个遍历器的作用域:

    // since C++20
    auto Func2 = []<typename T, typename F>(T && t, F && f) {
        [&] <size_t ...I>(std::index_sequence<I...>) {
            ((f(std::get<I>(t))), ...);
        }(std::make_index_sequence<std::tuple_size_v<std::remove_reference_t<T>>>{});
    };

然后我们还可以利用C++17提供给我们的std::apply取值:

// since C++17
class Func3 {
public:
    template<typename T, typename F>
    auto operator()(T&& t, F&& f) {
        std::apply(
            [&f](auto&&... args) {
                ((f(args)), ...);
            }, t
        );
    }
};

或者干脆把这个std::apply给拿出来,这种应该算是最简单的:

// since C++17
std::apply(
    [&PrintV](auto&&... args) {
        ((PrintV(args)), ...);
    }, t
);

完整测试程序:

#include <iostream>
#include <tuple>
#include <type_traits>
#include <initializer_list>


// since C++14
class Func0 {
    template<typename T, typename F, size_t... I>
    void init(T&& t, F&& f, std::index_sequence<I...>) {
        std::initializer_list<int>{ (f(std::get<I>(t)), 0)... };
    }
public:
    template<typename T, typename F>
    auto operator()(T&& t, F&& f) {
        init(t, f, std::make_index_sequence<std::tuple_size_v<std::remove_reference_t<T>>>{});
    }
};

// since C++17
class Func1 {
    template<typename T, typename F, size_t... I>
    void init(T&& t, F&& f, std::index_sequence<I...>) {
        ((f(std::get<I>(t))), ...);
    }
public:
    template<typename T, typename F>
    auto operator()(T&& t, F&& f) {
        init(t, f, std::make_index_sequence<std::tuple_size_v<std::remove_reference_t<T>>>{});
    }
};

// since C++17
class Func3 {
public:
    template<typename T, typename F>
    auto operator()(T&& t, F&& f) {
        std::apply(
            [&f](auto&&... args) {
                ((f(args)), ...);
            }, t
        );
    }
};


int main(int argc, char* argv[])
{
    // 测试一下
    // auto t = std::make_tuple(1, 2.f, 3., '4', "5");  // for C++14
    std::tuple t(1, 2.f, 3., '4', "5"); 
    auto PrintV = [](auto&& v) { std::cout << v << ' '; };

    Func0()(t, PrintV);
    std::cout << "\n\n";
    
    Func1()(t, PrintV);
    std::cout << "\n\n";
    
    // since C++20
    auto Func2 = []<typename T, typename F>(T && t, F && f) {
        [&] <size_t ...I>(std::index_sequence<I...>) {
            ((f(std::get<I>(t))), ...);
        }(std::make_index_sequence<std::tuple_size_v<std::remove_reference_t<T>>>{});
    };
    Func2(t, PrintV);
    std::cout << "\n\n";
    
    Func3()(t, PrintV);
    std::cout << "\n\n";

    // since C++17
    std::apply(
        [&PrintV](auto&&... args) {
            ((PrintV(args)), ...);
        }, t
    );
    std::cout << "\n\n";
    return 0;
}

输出结果:
C++遍历std::tuple(C++14 ~ C++20),c++,开发语言文章来源地址https://www.toymoban.com/news/detail-654615.html

到了这里,关于C++遍历std::tuple(C++14 ~ C++20)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C++标准学习--tuple

    以下帖子介绍的比较详细: C++的 tuple_c++ tuple-CSDN博客 tuple 是 C++11 新标准里的类型,它是一个类似 pair 类型的模板。tuple 是一个固定大小的不同类型值的集合,是泛化的 std::pair。我们也可以把它当做一个通用的结构体来用,不需要创建结构体又获取结构体的特征,在某些情况

    2024年02月02日
    浏览(30)
  • C++(11):判断tuple是否含有某个类型

    有的时候需要判断tuple中是否有个某个类型,可以借助变长模板的递归调用方式进行检查: C++(11):变长模板_变长模板参数 c++11-CSDN博客 另外还使用了true_type和false_type:

    2024年02月04日
    浏览(45)
  • 【C++ STL之string,tuple,array详解】

    在C++的STL(Standard Template Library)中,std::string是一个非常有用的字符串类。它提供了一系列操作字符串的功能,包括字符串的创建、修改、查找、拼接等。本文将详细介绍C++ STL中std::string的使用方法和一些常见操作。 (1) 支持比较运算符 string字符串支持常见的比较操作符(

    2024年02月12日
    浏览(50)
  • C++中神奇的tuple:详解使用技巧和实例解析

    在C++中,tuple是一种数据结构,用于将多个值组合在一起,形成一个有序的元组。每个值在tuple中都有一个对应的索引,可以通过索引来访问和操作其中的值。 作用: tuple将多个值组合在一起,形成一个整体。这些值可以是不同的数据类型,例如整数、浮点数、字符串等。

    2024年02月02日
    浏览(30)
  • linux如何查看编译器支持的C++版本(支持C++11、支持C++14、支持C++17、支持C++20)(编译时不指定g++版本,默认使用老版本编译)

    C++11 C++11是一个重要的C++标准版本,于2011年发布。C++11带来了许多重要的改进,包括: 智能指针:引入了shared_ptr和unique_ptr等智能指针,用于更好地管理动态内存分配。 新的循环语句:引入了for循环中的范围语法,以更简洁的方式遍历容器。 初始化列表:允许使用初始化列表

    2024年02月02日
    浏览(36)
  • UG NX二次开发(C++)-用UF_OBJ_cycle_objs_in_part遍历对象

    UG NX二次开发中,比如体、面、边等,在NXOpen中可以通过Collection来实现,但是采用遍历对象的方式也能实现,这就要需要UF_OBJ_cycle_objs_in_part的函数。本文就介绍一下这个方法的使用。 打开UG NX软件,在UG NX视图区创建多个特征,如下图所示: 这个三维模型中,包含了三个长方

    2024年02月02日
    浏览(36)
  • ​第20课 在Android Native开发中加入新的C++类

    ​这节课我们开始利用ffmpeg和opencv在Android环境下来实现一个rtmp播放器,与第2课在PC端实现播放器的思路类似,只不过在处理音视频显示和播放的细节略有不同。 1.压缩备份上节课工程文件夹并修改工程文件夹为demo20,将demo20导入到Eclipse或者在原工程上继续下列的开发步骤。

    2024年01月25日
    浏览(41)
  • 14-5_Qt 5.9 C++开发指南_基于HTTP 协议的网络应用程序

    Qt 网络模块提供一些类实现 OSI 7 层网络模型中高层的网络协议,如 HTTP、FTP、SNMP等,这些类主要是 QNetworkRequest、QNetworkReply和QNetworkAccessManager。 QNetworkRequest 类通过一个URL 地址发起网络协议请求,也保存网络请求的信息,目前支持 HTTP、FTP 和局部文件 URLs的下载或上传。 QNe

    2024年02月13日
    浏览(51)
  • C++面试八股文:用过std::set/std::map吗?

    某日二师兄参加XXX科技公司的C++工程师开发岗位第27面: 面试官:用过 std::set/std::map 吗? 二师兄:用过。 面试官:能介绍一下二者吗? 二师兄: std::set 是一个有序的集合,其中的元素是唯一的,即每个元素只能出现一次。一般用于去重和自动排序。 二师兄: std::map 同样是

    2024年02月11日
    浏览(55)
  • C++并发编程:std::future、std::async、std::packaged_task与std::promise的深度探索

    1.1 并发编程的概念 (Concept of Concurrent Programming) 并发编程是一种计算机编程技术,其核心在于使程序能够处理多个任务同时进行。在单核处理器上,虽然任何给定的时间只能运行一个任务,但通过任务切换,可以创建出并发执行的效果。而在多核处理器上,可以真正同时处理

    2024年02月05日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包