当前位置: 首页 > news >正文

c++14概述

C++14

概述

C++14 包含以下新的语言特性:

  • 二进制字面量
  • 通用 lambda 表达式
  • lambda 捕获初始化器
  • 返回类型推导
  • decltype(auto)
  • 放宽 constexpr 函数的约束
  • 变量模板
  • [[deprecated]] 属性

C++14 包含以下新的库特性:

  • 标准库类型的用户自定义字面量
  • 编译期整数序列
  • std::make_unique

C++14 语言特性

二进制字面量

二进制字面量提供了一种便捷的方式来表示二进制(基数为2)数字,还可以使用'分隔数字位以提升可读性。

0b110 // 等于 6 0b1111'1111 // 等于 255

通用 lambda 表达式

C++14 允许在 lambda 表达式的参数列表中使用auto类型说明符,从而支持多态 lambda。

auto identity = [](auto x) { return x; }; int three = identity(3); // 等于 3 std::string foo = identity("foo"); // 等于 "foo"

lambda 捕获初始化器

该特性允许使用任意表达式初始化 lambda 捕获的变量。捕获值的命名无需与外围作用域中的变量相关联,且会在 lambda 体内部引入一个新名称。初始化表达式在 lambda创建(而非调用)时求值。

int factory(int i) { return i * 10; } auto f = [x = factory(2)] { return x; }; // 返回 20 auto generator = [x = 0] () mutable { // 如果没有 'mutable',此代码无法编译,因为每次调用都会修改 x return x++; }; auto a = generator(); // 等于 0 auto b = generator(); // 等于 1 auto c = generator(); // 等于 2

此前,lambda 仅能通过拷贝或引用捕获变量,现在则可以将值移动(或转发)到 lambda 中,因此能够按值捕获仅可移动类型。注意,下述示例中task2捕获列表里=左侧的p是 lambda 体私有的新变量,与原p无关。

auto p = std::make_unique<int>(1); auto task1 = [=] { *p = 5; }; // 错误:std::unique_ptr 无法拷贝 // 对比 auto task2 = [p = std::move(p)] { *p = 5; }; // 正确:p 被移动构造到闭包对象中 // 创建 task2 后,原 p 变为空

通过该特性,引用捕获的变量可以使用与原变量不同的名称。

auto x = 1; auto f = [&r = x, x = x * 10] { ++r; return r + x; }; f(); // 将 x 设为 2,并返回 12

返回类型推导

在 C++14 中使用auto作为返回类型时,编译器会尝试为你推导具体类型。对于 lambda 表达式,现在也可以通过auto推导其返回类型,这使得返回推导所得的引用或右值引用成为可能。

// 推导返回类型为 `int`。 auto f(int i) { return i; }
template <typename T> auto& f(T& t) { return t; } // 返回推导类型的引用。 auto g = [](auto& x) -> auto& { return f(x); }; int y = 123; int& z = g(y); // 指向 `y` 的引用

decltype(auto)

decltype(auto)类型说明符与auto一样会推导类型,但它在推导返回类型时会保留引用和 cv 限定符(const/volatile),而auto不会。

const int x = 0; auto x1 = x; // int decltype(auto) x2 = x; // const int int y = 0; int& y1 = y; auto y2 = y1; // int decltype(auto) y3 = y1; // int& int&& z = 0; auto z1 = std::move(z); // int decltype(auto) z2 = std::move(z); // int&&
// 注意:在泛型代码中尤其有用! // 返回类型为 `int`。 auto f(const int& i) { return i; } // 返回类型为 `const int&`。 decltype(auto) g(const int& i) { return i; } int x = 123; static_assert(std::is_same<const int&, decltype(f(x))>::value == 0); static_assert(std::is_same<int, decltype(f(x))>::value == 1); static_assert(std::is_same<const int&, decltype(g(x))>::value == 1);

另见:decltype (C++11)

放宽 constexpr 函数的约束

在 C++11 中,constexpr函数体仅能包含有限的语法,包括(但不限于):typedefusing以及单个return语句。C++14 大幅扩展了允许的语法范围,支持最常用的语法,如if语句、多个return语句、循环等。

constexpr int factorial(int n) { if (n <= 1) { return 1; } else { return n * factorial(n - 1); } } factorial(5); // 等于 120

变量模板

C++14 允许对变量进行模板化:

template<class T> constexpr T pi = T(3.1415926535897932385); template<class T> constexpr T e = T(2.7182818284590452353);

[[deprecated]] 属性

C++14 引入[[deprecated]]属性,用于标记不建议使用的单元(函数、类等),使用这类单元通常会触发编译警告。若指定了原因,该原因会包含在警告信息中。

[[deprecated]] void old_method(); [[deprecated("请改用 new_method")]] void legacy_method();

C++14 库特性

标准库类型的用户自定义字面量

为标准库类型新增了用户自定义字面量,包括针对chronobasic_string的新内置字面量。这些字面量可以是constexpr,意味着它们能在编译期使用。这类字面量的用途包括编译期整数解析、二进制字面量以及虚数字面量等。

using namespace std::chrono_literals; auto day = 24h; day.count(); // 等于 24 std::chrono::duration_cast<std::chrono::minutes>(day).count(); // 等于 1440

编译期整数序列

类模板std::integer_sequence表示一个编译期整数序列。基于它实现了一些辅助工具:

  • std::make_integer_sequence<T, N>- 创建类型为T、包含0, ..., N - 1的序列。
  • std::index_sequence_for<T...>- 将模板参数包转换为整数序列。

示例:将数组转换为元组

template<typename Array, std::size_t... I> decltype(auto) a2t_impl(const Array& a, std::integer_sequence<std::size_t, I...>) { return std::make_tuple(a[I]...); } template<typename T, std::size_t N, typename Indices = std::make_index_sequence<N>> decltype(auto) a2t(const std::array<T, N>& a) { return a2t_impl(a, Indices()); }

std::make_unique

std::make_unique是创建std::unique_ptr实例的推荐方式,原因如下:

  • 避免手动使用new运算符。
  • 避免指定指针持有的底层类型时重复代码。
  • 最重要的是,它提供异常安全性。例如,假设我们像这样调用函数foo
foo(std::unique_ptr<T>{new T{}}, function_that_throws(), std::unique_ptr<T>{new T{}});

编译器可能会先调用new T{},再调用function_that_throws(),以此类推……由于我们在第一个T的构造过程中在堆上分配了内存,此处会引入内存泄漏。使用std::make_unique则能保证异常安全:

foo(std::make_unique<T>(), function_that_throws(), std::make_unique<T>());

关于std::unique_ptrstd::shared_ptr的更多信息,参见智能指针 (C++11) 部分。

http://www.jsqmd.com/news/723708/

相关文章:

  • 打造纯净供应链:Ledger官方授权杜绝一切中间风险环节
  • 使用 20 年后告别!Emacs 替代工具开发完成,新工具优势大
  • LLaMA-Factory结合DPO实现偏好对齐(RLHF简化方案)-方案选型对比
  • Fortran数组运算与循环优化实操案例详解
  • 从Django REST framework看NotImplementedError:打造更健壮的API视图与序列化器
  • 模型推理速度翻倍?深入浅出聊聊YOLO里的‘RepConv’重参数化黑科技
  • AI驱动知识管理市场爆发:2026年企业数字化转型的“必答题“
  • 2026金三银四,Java竞争依旧激烈!
  • 2026年Redis入门保姆级教程:从缓存到消息队列,搞懂互联网快如闪电的秘密
  • CentOS/Openeuler主机中,为一个网卡设置多个IP地址
  • SAP采购订单消息输出配置避坑指南:从NACE到OMQN,手把手解决ME23N状态不变绿问题
  • A-index框架:突破深度伪造检测的对抗鲁棒性挑战
  • “钱去哪了?”被董事会问住之后:一家中型制造厂的ERP上线实录
  • 【无标题】重磅!沉寂15个月,DeepSeek-V4预览版发布,开源大模型迎全新突破
  • GitHub Copilot 6 月 1 日起转向基于使用量计费,能否解决成本难题?
  • R 4.5 + xts 0.13.1 + blotter 0.15.0 组合下,你的策略年化夏普比率为何突然下降0.7?(回测一致性断层预警)
  • 用Python的FastICA从混合音频里分离人声和噪音:一个保姆级实战教程
  • 留美噩梦:毕业即失业?美国冻结40国OPT审批,百万份申请陷入“无底洞”!
  • 2026年上海徐汇GEO优化公司排名揭晓,靠谱品牌推荐不容错过 - 工业品牌热点
  • 从noexcept到noexcept_strict,C++27异常契约强化全解析,深度解读ISO/IEC 14882:2027第15.4.6节新增约束条款
  • OECT直接通过脚本切换系统盘
  • XMGV系列微型音圈电机模组解析
  • 告别NMS!RT-DETR实时端到端目标检测实战(基于PyTorch,附代码)
  • 微步N10迷你主机评测:i3-N305性能与工业应用解析
  • HTML转Figma:5步实现网页设计稿的智能逆向工程
  • 精密铸造领域核心耗材供应企业推荐:从钢料到脱氧剂的全链条解决方案 - 品牌策略师
  • 项目材料收发存汇总软件怎么用更合适?先分清适用场景、岗位分工和落地边界
  • VMware Workstation Pro 17免费激活终极指南:从零开始快速获取完整许可证
  • 大模型上线前最后一道防线:R语言驱动的实时偏见流式监测架构(支持API级响应延迟<87ms,已通过金融级合规审计)
  • 嵌入式USB通信设计:从基础到高级应用