返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C++11中跳转initializer_list怎么实现
  • 952
分享到

C++11中跳转initializer_list怎么实现

2023-06-29 20:06:15 952人浏览 八月长安
摘要

本篇内容介绍了“c++11中跳转initializer_list怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1.初始化列表的实现(

本篇内容介绍了“c++11中跳转initializer_list怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

1.初始化列表的实现

(1)当编译器看到{t1,t2&hellip;tn}时便会生成一个initializer_list<T>对象(其中的T为元素的类型),它关联到一个array<T,n>

(2)对于聚合类型,编译器会将array<T,n>内的元素逐一分解并赋值给被初始化的对象。这相当于为该对象每个字段分别赋值

(3)对于非聚合类型。如果该类存在一个接受initializer_list<T>类型的构造函数,则初始化时会将initializer_list<T>对象作为一个整体传给构造函数。如果不存在这样的构造函数,则array内的元素会被编译器分解并传给相应的能接受这些参数的构造函数(比如列表中有2个元素的,就传给带2个参数的构造函数。有3个元素的,就传给带3个参数的构造函数,依此类推&hellip;&hellip;)。

【实例分析】initializer_list<T>初体验

#include <iOStream>#include <vector>#include <map>#include <complex>using namespace std;//编译选项:g++ -std=c++11 test1.cpp -fno-elide-constructorsclass Foo{public:    Foo(int)    {        cout << "Foo(int)"<< endl;    }        Foo(int, int)        cout << "Foo(int, int)"<< endl;    Foo(const Foo& f)        cout << "Foo(const Foo& f)"<< endl;};int main()    Foo f1(123);    Foo f2 = 123;   //先将调用Foo(int)将123转为Foo对象,再调用拷贝构造函数(后面这步可能被优化)    Foo f3 = {123}; //生成initializer_list<int>,然后分解元素后,由于列表中只有1个元素,所以将其传给Foo(int)    Foo f4 = {123, 321}; //生成initializer_list<int>,然后分解元素后,由于列表中有两个元素,所以将其传给Foo(int, int)    //编译器会为以下花括号形成一个initializer_list<string>,背后有个array<string,6>    //调用vector<string>的构造函数时,编译器会找到一个接受initializer_list<string>    //的重载的构造函数。所有的容器均有这样的构造函数。在这个构造函数里会利用    //initializer_list<string>来初始化。    vector<string> city{"Berlin", "New York", "London", "Cairo","Tokyo", "Cologne"};    //编译器会为以下花括号形成一个initializer_list<double>,背后有个array<double,2>。    //调用complex<double>的构造函数时,array内的2个元素被分解并传给    //Comlex<double>(double,double)这个带有两个参数的构造函数。因为comlex<double>并无    //任何接受initializer_list的构造函数。    complex<double> c{4.0, 3.0}; //等价于c(4.0, 3.0)    return 0;}

2. initializer_list<T>模板

//initializer_list<T>源码分析

#include <iostream>template <class T>class initializer_list{public:    typedef T         value_type;    typedef const T&  reference; //注意说明该对象永远为const,不能被外部修改!    typedef const T&  const_reference;    typedef size_t    size_type;    typedef const T*  iterator;  //永远为const类型    typedef const T*  const_iterator;private:    iterator    _M_array; //用于存放用{}初始化列表中的元素    size_type   _M_len;   //元素的个数        //编译器可以调用private的构造函数!!!    //构造函数,在调用之前,编译会先在外部准备好一个array,同时把array的地址传入模板    //并保存在_M_array中    constexpr initializer_list(const_iterator __a, size_type __l)    :_M_array(__a),_M_len(__l){};  //注意构造函数被放到private中!    constexpr initializer_list() : _M_array(0), _M_len(0){} // empty list,无参构造函数    //size()函数,用于获取元素的个数    constexpr size_type size() const noexcept {return _M_len;}    //获取第一个元素    constexpr const_iterator begin() const noexcept {return _M_array;}    //最后一个元素的下一个位置    constexpr const_iterator end() const noexcept    {        return begin() + _M_len;    }  };

(1)initializer_list是一个轻量级的容器类型,内部定义了iterator等容器必需的概念,本质上是一个迭代器

(2)对于std:: initializer_list<T>而言,它可以接收任意长度的初始化列表,但要求元素必须是同种类型(T或可转换为T)。

(3)它有3个成员函数:size()、begin()和end()

(4)拥有一个无参构造函数,可以被直接实例化,此时将得到一个空的列表。之后可以进行赋值操作,如initializer_list<int> list; list={1,2,3,4,5};

(5)initializer_list<T>在进行复制或赋值时,它内部将保存着列表的地址保存在_M_array中,它进行的是浅拷贝,并不真正复制每个元素,因此效率很高。

编程实验】打印初始化列表的每个元素

#include <iostream>//打印初始化列表的每个元素void print(std::initializer_list<int> vals){    //遍历列表中的每个元素    for(auto p = vals.begin(); p!=vals.end(); ++p){        std::cout << *p << " ";    }        std::cout << std::endl;}//std::initializer_list<T>的浅拷贝。以下的返回值应改为std//以下的返回值应改为std::vector<int>类型,而不是std::initializer_list<int>类型。std::initializer_list<int> func(void)    int a = 1;    int b = 2;    return {a, b}; //编译器看到{a, b}时,会做好一个array<int,2>对象(其生命                   //期直至func结束),然后再产生一个initializer_list<int>                   //临时对象,由于initializer_list<int>采用的是浅拷贝,当                   //函数返回后array<int,2>会被释放,所以无法获取到列表中的元素!int main()    print({1,2,3,4,5,6,7,8,9,10});    print(func());    return 0;

3.让自定义的类可以接受任意长度初始化列表

(1)自定义类中重载一个可接受initializer_list<T>类型的构造函数

(2)在该构造函数中,遍历列表元素并赋值给相应的字段。

【编程实验】自定义类的初始化列表

#include <iostream>#include <map>using namespace std;class Foo{public:    Foo(int a, int b)    {        cout << "Foo(int a, int b)" << endl;    }        Foo(initializer_list<int> list)        cout << "Foo(initializer_list<int> list) : ";                for(auto i : list){            cout <<i<< " ";        }        cout << endl;};class FooMap    std::map<int, int> content;    using pair_t = std::map<int, int>::value_type;    FooMap(std::initializer_list<pair_t> list)        for(auto it = list.begin(); it!=list.end(); ++it){            content.insert(*it);                        std::cout << "{" << (*it).first <<"," <<(*it).second <<"}" << " ";        std::cout << std::endl;int main()    Foo f1(77, 5);     //Foo(int a, int b), a = 77, b = 5;    //注意:由于定义了Foo(initializer_list<int> list)函数,以下3种方    //式的初始化都会将{...}作为一个整体传递给该函数。如果没有定义该函    //数,则由于该类是个非聚合类用{}初始化时,会调用构造函数来初始化。    //但由于Foo类不存在3个参数的构造函数,所以f3那行会编译失败!    Foo f2{77, 5};     //Foo(initializer_list<int> list)    Foo f3{77, 5, 42}; //Foo(initializer_list<int> list)    Foo f4 = {77, 5};  //Foo(initializer_list<int> list)    FooMap fm = {{1,2}, {3,4},{5,6}};    return 0;}

“C++11中跳转initializer_list怎么实现”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

--结束END--

本文标题: C++11中跳转initializer_list怎么实现

本文链接: https://lsjlt.com/news/326335.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • C++11中跳转initializer_list怎么实现
    本篇内容介绍了“C++11中跳转initializer_list怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1.初始化列表的实现(...
    99+
    2023-06-29
  • C++11中跳转initializer_list实现分析
    目录1.初始化列表的实现2. initializer_list<T>模板3.让自定义的类可以接受任意长度初始化列表1.初始化列表的实现 (1)当编译器看到{t1,t2&h...
    99+
    2024-04-02
  • C++11的initializer_list形参怎么使用
    这篇文章主要讲解了“C++11的initializer_list形参怎么使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C++11的initializer_list形参怎么使用”吧!C语言...
    99+
    2023-06-19
  • C++ std::initializer_list实现原理是什么
    这篇文章主要讲解了“C++ std::initializer_list实现原理是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C++ std::initializer...
    99+
    2023-06-29
  • vuejs中怎么实现跳转传参
    这篇文章将为大家详细讲解有关vuejs中怎么实现跳转传参,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。 vue跳转传参的方法:1、通过rout...
    99+
    2024-04-02
  • JSP页面中怎么实现跳转
    JSP页面中怎么实现跳转,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。1. RequestDispatcher.forward() 是在服务器...
    99+
    2024-04-02
  • vue中怎么实现按钮跳转
    vue中实现按钮跳转的方法:1、在html文件中使用button标签设置按钮并添加点击事件;2、在vue的methods中添加方法实现页面跳转;3、通过浏览器查看设计效果即可。具体操作方法:在html文件中使用“button”标签设置一个按...
    99+
    2024-04-02
  • Flex中怎么实现页面跳转
    Flex中怎么实现页面跳转,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。Flex页面跳转实现Flex页面跳转以下几种方式:使用ViewStack组件,把要跳转的页新建成MX...
    99+
    2023-06-17
  • PHP中怎么实现页面跳转
    本篇文章给大家分享的是有关PHP中怎么实现页面跳转,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。1.PHP实现页面跳转***种方法<php header(&qu...
    99+
    2023-06-17
  • PHP中怎么实现指定跳转
    本文小编为大家详细介绍“PHP中怎么实现指定跳转”,内容详细,步骤清晰,细节处理妥当,希望这篇“PHP中怎么实现指定跳转”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。一、使用header()函数实现指定跳转PHP...
    99+
    2023-07-05
  • C++11中怎么实现参数绑定
    C++11中怎么实现参数绑定,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。lambda表达式的缺点还记得当初引入lambda表达式的原因么?向算法传递谓词时,由...
    99+
    2023-06-19
  • 怎么在html中实现页内跳转
    怎么在html中实现页内跳转?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。html有什么特点1、简易性:超级文本标记语言版本升级采用超集方式,从而更加灵活方便,适合初学前端...
    99+
    2023-06-14
  • 怎么在html中实现网页跳转
    今天就跟大家聊聊有关怎么在html中实现网页跳转,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。1、html中使用meta中跳转,通过meta可以设置跳转时间和页面<head&g...
    99+
    2023-06-14
  • 怎么在html中实现页面跳转
    怎么在html中实现页面跳转?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。html实现页面跳转的方法:html中使用meta中跳转,通过meta可以设置跳转时间和页面<...
    99+
    2023-06-14
  • 怎么在javascript中实现页面跳转
    本篇文章给大家分享的是有关怎么在javascript中实现页面跳转,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。javascript实现页面跳转的方法:1、通过修改窗体对象wi...
    99+
    2023-06-14
  • 什么是301跳转?PHP中怎么实现?
    在网站开发过程中,可能会出现需要将某个网页地址进行修改的情况。例如,网站改版,旧的网页地址已经失效,但是这些旧的网址已经被搜索引擎进行了收录,如果直接删除这些网页,会导致搜索引擎无法打开网页,从而影响网站的访问量和排名。针对这种情况,可以使...
    99+
    2023-05-14
    php 301
  • html怎么实现网址跳转
    这篇文章主要介绍“html怎么实现网址跳转”,在日常操作中,相信很多人在html怎么实现网址跳转问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”html怎么实现网址跳转”的疑惑...
    99+
    2024-04-02
  • 怎么实现全站301跳转
    实现全站301跳转的示例:在对应的ASP网站文件中添加以下代码:...
    99+
    2024-04-02
  • php header头怎么实现跳转
    php header实现跳转的方法:1、使用“Header("Location:$url");”语法实现跳转;2、使用if判断式实现跳转,其跳转语句如“if($_COOKIE["u_type"]){ ...
    99+
    2023-05-14
    php header
  • react怎么实现跳转页面
    本教程操作环境:Windows10系统、react18.0.0版、Dell G3电脑。react怎么实现跳转页面?react项目实现页面跳转更新:useNavigate()的使用import { useNavigate } from ...
    99+
    2023-05-14
    React
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作