IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 从C到C++___STL入门(五)初始化列表和其他 -> 正文阅读

[C++知识库]从C到C++___STL入门(五)初始化列表和其他

从C到C++___STL入门(五)初始化列表和其他

1. initializer_list模板类

C++11中新加入的initializer_list模板的设计目的是:

  1. 使得初始化语法更加简单
  2. 使得传递参数更加方便

1.1 C++11的初始化语法

在C++11以前我们的初始化语法是:

int a=10;
int a(10);

所有的C++基本类型都有以上两种等价的初始化语句
而对于结构体和对象来说,我们的初始化语句只能调用构造函数。

但是在C++11中,我们引入了更简单通用的初始化语法:

double a{100.0};
vector<double> c{0.22,0.3,11};//等价于vector<double> c({0.22,0.3,11});

以上就是新的初始化语法。对于C++基本类型来说,double a{100.0}成立的原因是,{}被视为();而对于类对象来说,vector<double> c{0.22,0.3,11}成立的原因是在vector类中存在一个构造函数,形如vector<T>(initializer_list<T> il)。所以说在这里{0.22,0.3,11}相当于是initializer_list<double>{0.22,0.3,11}

{}()的关系

而且狠crazy的一件事是,这里{}被视为()并不是强行解释:

struct A{
    int x;
    double y;
};
A a{12,13};

上面这一语法是正确的,但是我们知道对于结构体A来说,它并没有定义构造函数A(initializer_list<int>);但是上面这一初始化语法居然是正确的,所以唯一解释是,A a(12,13);即调用的隐式默认构造函数进行初始化。

vector<double> a{10};

现在,上面这一语句是调用构造函数vector<T>(size n)还是vector<T>(initializer_list<T> il);答案是后者,我们得明确这一事实:如果类中存在initializer_list的构造函数,那么它会优先将由初始化列表初始化的对象,解释为使用该构造函数,如果不能解释,它才会将{}视为(),以调用其他构造函数。

所以说,在今后的编程中能使用{}就是说我显式使用初始化列表语句,使用()就代表我使用的是某明确的构造函数。这实现了初始化语句的统一性

initializer_list不能进行narrowing

vector<int> a{1.0,2.3};

上述初始化语句是错误的,即说明initializer_list<double>不能进行隐式narrowinginitializer_list<int>

1.2 使用initializer_list进行参数传递

如果要在代码中使用initializer_list模板类,必须包含头文件initializer_list
实际上,initializer_list的更多的用处在于传递可变长的参数(相同类型)。但是很多人可能会使用vector<>来实现同样的目的,但是initializer_list更加轻量级,传参更快。

#include<initializer_list>
#include<iostream>
using namespace std;
template<class T>
T sum(initializer_list<T> a)
{
    T ret=0;
    for(auto &x :a)
        ret+=x;
    return ret;
}

int main()
{
    cout<<sum({1,2,3,5,6,7})<<endl;
}

如上所示就是可变长参数的函数,实际上也可以使用vector来替代initializer_list

而且我们使用按值传递,不采用引用传递,这是因为initializer_list对象本身很小,没必要传引用,而且这类的设计初衷就是为了传参,而且他这种容器,里面的元素都是const的。同样的,initializer_list容器也由一些类方法,例如begin()end()。值得注意的是,在STL容器中,所有的容器的接受initializer_list的构造函数都是采用的按值传递

2.其他STL知识

2.1 全排列算法

看一个好玩的STL函数:next_permutation(),全排列算法,这是一种排序算法,他会对容器中的内容进行排序,生成下一个排序(从小到大紧挨着的下一个排序)。如果发现容器中的元素已经是最大排列,那就返回false,否则返回true

#include<string>
#include<vector>
#include<iostream>
#include<algorithm>
using namespace std;

int main()
{
    string a{"abcd"};
    vector<int> b{1,2,3,4};
    cout<<a<<endl;
    while(next_permutation(a.begin(),a.end()))
    {
        cout<<a<<endl;
    }
    for(auto&x:b)cout<<x<<" ";
    cout<<endl;
    while (next_permutation(b.begin(),b.end()))
    {
           for(auto&x:b)cout<<x<<" ";
            cout<<endl;
    }
    
}
abcd
abdc
acbd
acdb
adbc
adcb
bacd
badc
bcad
bcda
bdac
bdca
cabd
cadb
cbad
cbda
cdab
cdba
dabc
dacb
dbac
dbca
dcab
dcba
1 2 3 4 
1 2 4 3
1 3 2 4
1 3 4 2
1 4 2 3
1 4 3 2
2 1 3 4
2 1 4 3
2 3 1 4
2 3 4 1
2 4 1 3
2 4 3 1 
3 1 2 4
3 1 4 2
3 2 1 4
3 2 4 1
3 4 1 2
3 4 2 1
4 1 2 3
4 1 3 2
4 2 1 3 
4 2 3 1
4 3 1 2
4 3 2 1

2.2 vector,arrayvalarray

在C++中提供3中数组模板:vector,arrayvalarray。但是它们的区别很大,它们完全是由不同的小组设计开发的,其中valarray不是STL容器,其他两个都是STL容器;vector是可变长数组,而array才是真正纯粹上的C数组替代品,它是固定长度的数组,valarray是一种数值计算的数组。

vector<int> vec(10);
array<int,10> arr;
valarray<int> val(10);

以上是3种初始化语句,可以发现,vectorvalarray的初始化类似,而array由于是不可变长的数组,它使用模板参数中的非类型参数来初始化数组长度。

array的应用情形就是替代C数组,而vector的应用情形就是可变长数组,而valarray的数值计算优势明显。

例如,我们想让array或者vector中的每一个元素乘以2.5

transform(x.begin(),x.end(),out.begin(),bind1st(multiplies<double>(),2.5));

而使用valarray就会简单很多

x*=2.5;//x=x*2.5

除此之外,valarray还重载了符号+,-,%等运算符。更通用的,它还具有方法apply()用以接受一个一元函数符。例如x.apply(log),即为容器中每一个元素做取对数运算。

而且valarray的通用性不好,因为它不是STL容器,它甚至没有begin()end()成员。而且它虽然做数值运算狠方便,但是并不意味着它的效率更高,他和vector的效率是一样的。

所以说,valarray是不太常用的容器。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-10-31 11:35:33  更:2022-10-31 11:36:08 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 4:36:48-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码