前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >全面盘点17个C++17的高级特性

全面盘点17个C++17的高级特性

作者头像
公众号guangcity
发布于 2024-03-22 04:56:47
发布于 2024-03-22 04:56:47
4K00
代码可运行
举报
文章被收录于专栏:光城(guangcity)光城(guangcity)
运行总次数:0
代码可运行

全面盘点17个C++17的高级特性

C++17是目前比较常用的版本之一,今天花时间来梳理一下17个重要特性,所有的特性也不止这么点。

1. 并行算法

C++17引入了许多并行版本的标准库中的算法。这些算法可以并行执行,因此在多核系统上可能会带来显著的性能提升。

之前写过一篇全面介绍这个特性的文章,可以看这篇:未来已来:C++17 并行STL性能测评

例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <algorithm>
#include <vector>
#include <execution>
int main() {
    std::vector<int> v = {1, 2, 3, 4, 5};
    std::sort(std::execution::par, v.begin(), v.end());
}

在此例子中,std::sort是并行执行的,以并行方式对向量v的元素进行排序。

2. If Initializers

C++17中的If初始化器是一项特性,它允许在if语句中直接初始化变量。这种初始化方式在一定程度上可以提高代码的可读性和简洁性。

在传统的C++中,我们通常会这样初始化变量:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int x;
if (condition) {
    x = 42;
} else {
    x = 24;
}

而在C++17中,可以使用if初始化器来简化这个过程,使代码更加紧凑:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
if (bool condition = /* some condition */) {
    int x = 42;
} else {
    int x = 24;
}

在这个例子中,我们将变量x的初始化直接放在if语句中。变量condition在if语句中被定义和初始化,然后在if语句块中可用。这种方式更加直观和简洁,尤其是在简单的条件初始化时。

3. 类模板参数推导(CTAD)

CTAD 让编译器从类参数中自动推导出模板参数。这使得在不必显式指定模板参数的情况下更容易地使用模板。

往期对这个特性的全面阐述文章:C++17那些事开篇之类模版参数推导(CTAD)

例如下面函数模版的例子(C++17之前):

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
template <typename T>
void foo(T t) {
    // ...
}

int main() {
    foo(42);  // 编译器推导出T的类型为int
}

在此例子中,当调用foo(42)时,编译器推导出T的类型是int.

4. template <auto>

模板关键词被引入为非类型模板参数的占位符。它允许在模板中表示任何类型的值。

例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
template<auto value>
struct constant {
    static constexpr auto get_value() { return value; }
};

// 用法
static_assert(constant<42>::get_value() == 42);

5. std::optional 和 std::variant

std::optionalstd::variant 是C++17中引入的两个新类型。std::optional 表示一个可能存在也可能不存在的值,std::variant 代表一个类型安全的联合,可以保存不同类型的值。

例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <optional>
#include <variant>

int main() {
    std::optional<int> opt = 42;
    std::variant<int, double> var = 3.14;
}

在这个例子中,opt是包含值42的可选整数,var是包含值3.14的变体。

6. 折叠表达式

在C++17中,折叠表达式提供了一种简洁的方式,用于对参数包执行二元操作。它们允许在不需要显式递归或迭代的情况下执行诸如求和、乘法或连接参数包中元素的操作。

例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <iostream>

template<typename T>
T sum(T t) {
    return t;
}

// 使用折叠表达式的递归情况
template<typename T, typename... Args>
T sum(T first, Args... args) {
    return first + sum(args...);
}

int main() {
    int total = sum(1, 2, 3, 4, 5);
    std::cout << "总和: " << total << std::endl;
    
    return 0;
}

递归sum函数中的折叠表达式(first + ... + args)对参数包中的每个元素应用了加法操作。

7. 结构化绑定

结构化绑定允许你将对象分解成其构成元素,类似于你可能会用到的元组拆包。

往期文章:C++17结构化绑定

例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <tuple>
#include <string>
int main() {
    std::tuple<int, std::string, double> t(42, "hello", 3.14);
    auto [i, s, d] = t;  // i = 42, s = "hello", d = 3.14
}

在此例子中,结构化绑定[i, s, d]将元组t分解成其构成元素。

8.模板模板参数

例如:在C++17中,语法 template<template<class...>typename bob> struct foo {} 声明了一个名为 foo 的模板,它接受一个名为 bob 的模板模板参数。模板模板参数 bob 本身接受任意数量的模板类型参数。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
template <template<class...> typename bob>
struct foo {
    template<typename T>
    void bar(const bob<T>& arg) {
        std::cout << "size: " << arg.size() << std::endl;
    }
};

int main() {
    foo<std::vector> f;
    std::vector<int> vec = {1, 2, 3, 4, 5};
    f.bar(vec);

    return 0;
}

main 函数中,我们使用 std::vector 实例化了 foo,将其作为 bob 的模板参数。这使我们能够创建一个通用的结构 foo,可以与任何接受任意数量类型参数的模板一起工作,例如 std::vectorstd::list 或用户定义的模板。

9. 内联变量

C++17允许在类的定义内部定义变量为内联的,这可以帮助减小二进制大小,可能通过防止变量在多个转换单元中的重复副本来提高性能。

例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class MyClass {
public:
    inline static int inlineVar = 42;
};

int main() {
    int localVar = MyClass::inlineVar;
}

在这里,inlineVarMyClass的内联静态成员变量。

10. 属性改进

C++17提供新的属性,并改进了已有的属性,允许开发人员为编译器提供更多的代码行为信息。

例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[[nodiscard]] int get_sum(int a, int b) {
    return a + b;
}

int main() {
    auto result = get_sum(1, 2);
    // 编译器可能会警告‘result’未使用
}

在此例子中,[[nodiscard]]是可以应用于函数的属性,表示其返回值不应该被调用者丢弃。

11. 嵌套命名空间

C++17通过折叠表达式增强了变参模板,使得在处理参数包时的代码更为简洁和表达明了。

例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 外部命名空间
namespace outer {
    // 内部命名空间
    namespace inner {
        void foo() {
            std::cout << "在内部命名空间中" << std::endl;
        }
    }
}

outer::inner::foo();

嵌套命名空间定义提供了一种将代码层次化组织的方式,提高了可读性和可维护性,尤其是在大型项目中。它们还通过提供更加结构化的命名空间层次结构来帮助避免命名冲突。

12. 字面量改进

C++17增强了字面量,包括对整数和浮点字面量的改进,以及对真和假字面量的支持。

例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
auto num = 123_456; // Underscore in integer literals  
auto pi = 3.1415_f; // Suffix for floating-point literals

13. constexpr Lambda

C++17允许lambda函数成为constexpr,如果它们满足条件,就可以在需要编译时评估的上下文中使用,例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
constexpr auto lambda = [](int x) { return x * 2; };
static_assert(lambda(5) == 10);

在这个例子中,lambda是一个constexpr lambda,它接受一个整数x作为参数,然后返回x的两倍。static_assert检查在编译时,lambda(5)的值是否等于10。

14. 捕获*this

在lambda中捕获*this变得更加简单,允许直接访问包含对象的成员。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Foo {
    int data = 42;
public:
    auto member_lambda() {
        return [*this] { std::cout << data << std::endl; };
    }
};

// 使用
Foo f;
f.member_lambda()(); // 输出 "42"

15. 扩展的if和switch语句

ifswitch语句中的条件现在可以是任何表达式,不仅限于布尔条件。这使得控制流更加灵活,例如使用结构化绑定时:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
if (const auto [it, inserted] = map.insert({"foo", bar}); inserted) {
    // ...
}

在此例子中,if语句检查inserted变量是否为真,但条件还包括结构化绑定的赋值。

16. 泛化的基于范围的for循环

此改进支持不同于起始迭代器类型的标志或结束迭代器,这有助于处理以空终止的循环和其他类似情况。例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
for (auto it = my_container.begin(); it != my_container.end(); ++it) {
   // ...
}

在此例子中,my_container可能是使用不同类型的结束迭代器的容器,但循环仍然可以正确工作。

17. if constexpr

此特性通过允许编译器在编译时评估条件,从而实现更通用的代码。如果条件为真,则编译的代码中包含if块内的代码;否则,它将被丢弃。这可以通过在运行时删除不必要的分支来简化代码。例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
if constexpr (std::is_same_v<T, int>) {
   // 用于int的特定代码
} else {
   // 用于其他类型的代码
}

在这个例子中,if constexpr语句检查类型T是否为int,并相应地包含适当的代码。

总结

本节就先写这么多,其他内容下一节进行阐述。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-03-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 光城 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
01.分布式文件系统FastDFS
FastDFS安装成功可通过/usr/bin/fdfs_test测试上传、下载等操作
全栈程序员站长
2022/06/30
2580
01.分布式文件系统FastDFS
Java开发环境系列:FastDFS分布式文件系统搭建(linux)
FastDFS 是一个开源的高性能分布式文件系统(DFS)。 它的主要功能包括:文件存储,文件同步和文件访问,以及高容量和负载平衡。主要解决了海量数据存储问题,特别适合以中小文件(建议范围:4KB < file_size <500MB)为载体的在线服务。 
架构师小跟班
2019/08/06
1.8K0
Java开发环境系列:FastDFS分布式文件系统搭建(linux)
【FastDFS】FastDFS 分布式文件系统的安装与使用,看这一篇就够了!!
作者个人研发的在高并发场景下,提供的简单、稳定、可扩展的延迟消息队列框架,具有精准的定时任务和延迟队列处理功能。自开源半年多以来,已成功为十几家中小型企业提供了精准定时调度方案,经受住了生产环境的考验。为使更多童鞋受益,现给出开源框架地址:
冰河
2020/10/29
1.2K0
【FastDFS】FastDFS 分布式文件系统的安装与使用,看这一篇就够了!!
分布式文件存储系统FastDFS从安装到入门
本文主要描述如何在Centos7下安装FastDFS,从介绍到概念,以及描述分布式部署以及单机部署的方式。
Devops海洋的渔夫
2022/01/17
6430
分布式文件存储系统FastDFS从安装到入门
Linux脚本一键安装配置Nginx+FastDFS
下载地址:https://github.com/AlEinstein/install_package/tree/master/linux/nginx%2Bfastdfs
静谧星空TEL
2021/04/27
7520
CentOS操作系统搭建FastDFS分布式文件系统
FastDFS 是一个开源的分布式文件系统,它对文件进行管理,功能包括:文件存储、文件同步、文件访问(文件上传、文件下载)等,解决了大容量存储和负载均衡的问题。特别适合以文件为载体的在线服务,如相册网站、视频网站等等。 昨天晚上就看到群友在群里问谁会装 FastDFS,我本着一颗善良之心,就答应给装一下,虽然是 JAVA 的,反正今天老板让加班也没事干,就折腾一下吧。从早上更新 Xshell 又重装 Xshell,到下午才给搞好,真是累。由于 FastDFS 集群搭建非常复杂,对于初期学习 FastDFS
沈唁
2018/05/24
5900
分布式文件系统(HDFS和FastDFS)
FastDFS 是一个开源的高性能分布式文件系统(DFS)。 它的主要功能包括:文件存储,文件同步和文件访问,以及高容量和负载平衡。主要解决了海量数据存储问题,特别适合以中小文件(建议范围:4KB < file_size <500MB)为载体的在线服务。
码客说
2020/10/23
5.2K0
分布式文件系统FastDFS安装配置
FastDFS是一个开源的轻量级分布式文件系统,它对文件进行管理,功能包括:文件存储、文件同步、文件访问(文件上传、文件下载)等,解决了大容量存储和负载均衡的问题。特别适合以文件为载体的在线服务。
BUG弄潮儿
2022/06/30
1.1K0
分布式文件系统FastDFS安装配置
FastDFS分布式文件上传系统的搭建
https://sourceforge.net/projects/fastdfs/
lyb-geek
2018/10/24
1.8K0
FastDFS分布式文件上传系统的搭建
【FastDFS】面试官:如何实现文件的大规模分布式存储?(全程实战)
作者个人研发的在高并发场景下,提供的简单、稳定、可扩展的延迟消息队列框架,具有精准的定时任务和延迟队列处理功能。自开源半年多以来,已成功为十几家中小型企业提供了精准定时调度方案,经受住了生产环境的考验。为使更多童鞋受益,现给出开源框架地址:
冰河
2020/10/29
1.1K0
CentOS7 搭建FastDFS分布式文件系统(上)
FastDFS的作者淘宝资深架构余庆,这个优秀的轻量及的分布式文件系统的开源没多久,立马就火了。FastDFS是为互联网应用量身定做的一套分布式文件存储系统,非常适合用来存储用户图片、视频、文档等文件。对于互联网应用,和其他分布式文件系统相比,优势非常明显。
胡齐
2019/09/23
7360
CentOS7 搭建FastDFS分布式文件系统(上)
FastDFS文件管理系统安装配置
FastDFS 是一个开源的高性能分布式文件系统(DFS)。 它的主要功能包括:文件存储,文件同步和文件访问,以及高容量和负载平衡。主要解决了海量数据存储问题,特别适合以中小文件(建议范围:4KB < file_size <500MB)为载体的在线服务。
星哥玩云
2022/07/25
3520
FastDFS文件管理系统安装配置
使用CentOS 7搭建FastDFS分布式文件系统教程
“每个理性的IT人士都置顶了吴柯的运维笔记” FastDFS是一个开源的轻量级分布式文件系统,它对文件进行管理,功能包括:文件存储、文件同步、文件访问(文件上传、文件下载)等,解决了大容量存储和负载均
吴柯
2018/04/19
1.7K0
使用CentOS 7搭建FastDFS分布式文件系统教程
【FastDFS】小伙伴们说在CentOS 8服务器上搭建FastDFS环境总报错?
作者个人研发的在高并发场景下,提供的简单、稳定、可扩展的延迟消息队列框架,具有精准的定时任务和延迟队列处理功能。自开源半年多以来,已成功为十几家中小型企业提供了精准定时调度方案,经受住了生产环境的考验。为使更多童鞋受益,现给出开源框架地址:
冰河
2020/10/29
6420
【FastDFS】小伙伴们说在CentOS 8服务器上搭建FastDFS环境总报错?
Linux安装Fastdfs
3.上传 "libfastcommon_v1.40.zip" 文件到当前目录(/data/libfastcommon)
shaun
2023/10/26
3480
Linux安装Fastdfs
分布式文件系统FastDFS安装配置
FastDFS是一个分布式的文件系统,他可以把上传到某一台服务器的文件分发复制到其他节点的文件服务器上做高可用。
算法之名
2019/08/20
8310
fastdfs 上传文件(nginx文件上传服务器)
FastDFS开源地址:https://github.com/happyfish100 参考:分布式文件系统FastDFS设计原理 参考:FastDFS分布式文件系统
全栈程序员站长
2022/07/31
13.7K0
fastdfs 上传文件(nginx文件上传服务器)
CentOS8安装fastdfs6.06
fastdfs-nginx-module,libfastcommon,fastdfs
享智同行
2020/01/06
1.1K1
CentOS8安装fastdfs6.06
CentOS7 fastdfs安装与测试
Fast DFS安装(3个storage server,2个trackerserver,安装在3个虚拟机上) tracker安装 wget https://codeload.github.com/happyfish100/libfastcommon/zip/master -O libfastcommon-master.zip unzip libfastcommon-master.zip cd libfastcommon-master/ ./make.sh ./make.sh install ln -s
肖哥哥
2020/08/06
7160
fastDFS和nginx配置
回到家目录 cd ~ 新建packages目录(用于存放 下载的包) mkdir packages
lesM10
2019/08/26
1.9K0
fastDFS和nginx配置
相关推荐
01.分布式文件系统FastDFS
更多 >
LV.1
这个人很懒,什么都没有留下~
目录
  • 全面盘点17个C++17的高级特性
  • 1. 并行算法
  • 2. If Initializers
  • 3. 类模板参数推导(CTAD)
  • 4. template <auto>
  • 5. std::optional 和 std::variant
  • 6. 折叠表达式
  • 7. 结构化绑定
  • 8.模板模板参数
  • 9. 内联变量
  • 10. 属性改进
  • 11. 嵌套命名空间
  • 12. 字面量改进
  • 13. constexpr Lambda
  • 14. 捕获*this
  • 15. 扩展的if和switch语句
  • 16. 泛化的基于范围的for循环
  • 17. if constexpr
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档