C++17
文章平均质量分 78
C咖咖
历史不会简单的重复,但历史会惊人的相似
展开
-
C++之异常处理
1. 异常基本用法2.异常和函数调用区别3. noexcept4. c++17 noexcept原创 2019-12-12 20:20:30 · 153 阅读 · 1 评论 -
lvalue xvalue prvalue
左值右值将亡值原创 2023-03-19 15:21:49 · 382 阅读 · 1 评论 -
std::tuple 遍历 传递到函数参数
#include <iostream>#include <tuple>struct Drx{ int a;};struct Mg{ int b;};class MsgBuilder{public: void addData(const Drx& drx){ std::cout << "Drx:" << drx.a << std::endl; } v...原创 2021-12-09 17:02:27 · 834 阅读 · 0 评论 -
C++17之编译时期if
在使用if constexpr(…)语法时,编译器在编译时期使用编译时期表达式决定是否使用if语句或then部分或else部分(如果有的话)。如果其中一个分支条件成立,则另一部分(如果有的话)被丢弃,这样也就不会生成被丢弃部分的代码。但是,这并不意味着被丢弃的部分完全被忽略,它就像未使用模板的代码一样检查语法等。例 1:#include <iostream>#include...原创 2019-09-04 07:47:43 · 2986 阅读 · 2 评论 -
C++17之折叠表达式
从c++ 17起,有一个特性可以计算在一个参数包的所有参数上使用二进制运算符的结果(带有一个可选的初值)。例如,下面的函数返回所有传递参数的和:#include <iostream>#include <string>template<typename... T>auto foldSum1(T... args){ return (... + ...原创 2019-09-05 20:30:58 · 5321 阅读 · 3 评论 -
C++17之字符串作为模板参数
随着时间的推移,c++的不同版本放宽了用作模板参数的规则,而在c++ 17中,这种情况再次发生。现在可以使用模板,而不需要在当前范围之外定义它们。 非类型模板参数只能是常量整数值(包括枚举)、指向对象/函数/成员的指针、指向对象或函数的lvalue引用,或者std::nullptr_t (nullptr的类型)。 对于指针,需要链接,这意味着不能直接传递字符串文本。但是...原创 2019-09-05 21:30:23 · 7226 阅读 · 0 评论 -
C++17之占位符类型作为模板参数
因为c++ 17可以使用占位符类型(auto和decltype(auto))作为非类型模板参数类型。这意味着,我们可以为不同类型的非类型参数编写通用代码。1. auto作为模板参数从c++ 17起,可以使用auto来声明一个非类型模板参数。例如:template<auto N> class S {...};这允许我们为不同类型实例化非类型模板参数N:S<...原创 2019-09-05 21:37:08 · 1931 阅读 · 0 评论 -
C++17之扩展using声明
using声明被扩展了,允许使用逗号分隔声明列表,允许在包扩展中使用声明。例如,现在可以编程:例1:#include <iostream>class Base {public: void a(); void b(); void c();};class Derived : private Base {public: using...原创 2019-09-05 21:42:04 · 1422 阅读 · 1 评论 -
C++17之std::optional
在编程中,我们经常遇到这样的情况:我们可能返回/传递/使用某种类型的对象。也就是说,我们可以有某个类型的值,也可以没有任何值。因此,我们需要一种方法来模拟类似指针的语义,在指针中,我们可以使用nullptr来表示没有值。处理这个问题的方法是定义一个特定类型的对象,并用一个额外的布尔成员/标志来表示值是否存在。std::optional<>以一种类型安全的方式提供了这样的对象。...原创 2019-09-05 21:53:14 · 37363 阅读 · 6 评论 -
C++17之std::variant
从C中采用的c++提供了对union的支持,union是能够保存可能类型列表之一的对象。但是,这种语言特性也有一些缺点:对象不知道它们当前持有的值的类型。 由于这个原因,您不能有non-trivial的成员,比如std::string(从c++ 11起, union原则上可以有non-trivial的成员,但是必须实现特殊的成员函数,比如复制构造函数和析构函数,因为只有通过代码逻辑才...原创 2019-09-05 21:55:25 · 38503 阅读 · 5 评论 -
C++17之std::visit
它们必须明确地为每种可能的类型提供函数调用操作符。然后,使用相应的重载来处理当前的备选项类型。1. 使用对象函数方式访问例1:#include <iostream>#include <variant>#include <string>struct MyVisitor{ void operator()(double d) c...原创 2019-09-05 21:58:17 · 17583 阅读 · 2 评论 -
C++17之std::any
一般来说,c++是一种具有类型绑定和类型安全性的语言。值对象声明为具有特定类型,该类型定义哪些操作是可能的以及它们的行为方式。值对象不能改变它们的类型。 std: any是一种值类型,它能够更改其类型,同时仍然具有类型安全性。也就是说,对象可以保存任意类型的值,但是它们知道当前保存的值是哪种类型。在声明此类型的对象时,不需要指定可能的类型。 诀窍在于,对象同时拥有包含的...原创 2019-09-05 22:00:11 · 36071 阅读 · 0 评论 -
C++17之std::byte
程序在内存中保存数据。在c++ 17引入了 一种std::byte类型,它确实表示内存元素的“nature”类型字节。与char或int类型的关键区别在于,它不是字符类型且非算术类型。 byte 只是位的汇集,而且只对它定义逐位运算符。即唯一支持的“计算”操作是位操作符。1. std::byte的使用下面的例子演示了std::byte:#include <cstddef>...原创 2019-09-05 22:01:33 · 12798 阅读 · 0 评论 -
C++17之std::string_review字符串视图
背景在进行参数传递时,当数据占用的内存比较大是,减少数据的拷贝可以有效提升程序的性能。在C语言中使用的是指针,在C++中使用了安全性更高的引用类型。所以C++中const std::string&成为了传递只读数据的不二方式。但是从实践来看,也存在一些问题:字符串字面值、字符数组、字符串指针的传递仍要数据拷贝 这三类低级数据类型与string类型不同,传入时,编译器需要做隐式转换...原创 2019-09-05 22:03:15 · 697 阅读 · 0 评论 -
C++17之类模板参数类型推导指南
您可以定义特定的推导指南来提供额外的或修正现有的类模板参数演绎。例如,您可以定义,每当推导出一个Pair3的类型时,类型推断的操作应该像类型将通过值传递一样:template<typename T1, typename T2>struct Pair3{ T1 first; T2 second; Pair3(const T1& x, const ...原创 2019-09-02 11:17:22 · 2565 阅读 · 0 评论 -
C++17之类模板参数推导
在c++ 17之前,总是必须显式地指定类模板的所有模板参数类型。例如,:std::complex<double> c{5.1,3.3};//不能省略doublestd::mutex mx;std::lock_guard<std::mutex> lg(mx);//std::muext也不能省略c++ 17起,必须显式指定模板参数的约束得到了放宽。如果构造函数能...原创 2019-09-01 21:44:01 · 2238 阅读 · 0 评论 -
c++17之结构化绑定
结构化绑定允许通过对象的元素或成员初始化多个实体。例如,假设你定义了一个结构体包含两个成员:struct MyStruct{{ int i = 0; std::string s;};MyStruct ms;可以使用以下声明将该结构的成员直接绑定到新名称:auto [u,v] = ms;这里,u和v的名称就是所谓的结构化绑定。结构化绑定对于返...原创 2019-08-25 21:49:12 · 7187 阅读 · 3 评论 -
c++17之提供类似tuple API给结构化绑定
如前所述,您可以像标准库为std::pair<>、std::tuple<>和std::array<>提供类似于元组的API一样,为任何类型添加对结构化绑定的支持。1. 只读结构化绑定下面的示例演示如何为类型Customer进行结构化绑定,其定义如下:customer1.hpp#include <iostream>#include ...原创 2019-08-26 11:20:26 · 835 阅读 · 0 评论 -
C++17之 Inline变量
c++的一个优点是它支持只使用头文件库的开发。然而,c++ 17之前,头文件中不需要或不提供全局变量或对象时才有可能成为一个库。c++ 17可以在头文件中定义一个内联的变量/对象,如果这个定义被多个编译单元使用,它们都指向同一个惟一的对象:class MyClass{ static inline std::string name = ""; // OK since C++17...原创 2019-08-27 22:00:56 · 12263 阅读 · 2 评论 -
C++17之聚合类扩展
在c++中初始化对象的一种方法是聚合初始化,它允许使用花括号从多个值初始化:struct Data{ std::string name; double value;};Data x{"test1", 6.778};在c++ 17中聚合可以有基类,所以对于从其他类/结构派生的结构,允许初始化列表:struct MoreData : Data{ ...原创 2019-08-29 15:03:07 · 625 阅读 · 1 评论 -
C++17之省略不必要的拷贝Copy Elision
从C++发展历史看来,c++ 17引入了一个规则,要求在满足一定的条件下避免对象的复制,这在以前是可选的。C++17中一个叫做强制复制省略的技术就是基于这个观点的。至少包括以下两项内容:1. 返回值优化(RVO),即通过将返回值所占空间的分配地点从被调用端转移至调用端的手段来避免拷贝操作。返回值优化包括具名返回值优化(NRVO)与无名返回值优化(URVO),两者的区别在于返回值是具名的...原创 2019-08-30 16:54:18 · 4905 阅读 · 2 评论 -
C++17之lambda扩展
c++ 11引入的Lambdas和用c++ 14引入的generic Lambdas都是成功的例子。lambda的使用使得我们在一些地方比函数方便很多。c++ 17改进了lambda的功能,允许在更多的地方使用lambdas: 在constant表达式(即,在编译时期); 在需要当前对象副本的地方(例如,在线程中调用lambdas时)。 1.constexpr ...原创 2019-08-31 23:21:28 · 1860 阅读 · 0 评论 -
C++17之嵌套的命名空间
c++标准委员会于2003年首次提出,最终接受嵌套名称空间的定义如下:namespace A::B::C {...}即等于:namespace A {namespace B{namespace C {...}}}注意,嵌套不支持内联命名空间。这仅仅是因为内联应用于最后一个名称空间还是应用于所有名称空间并不明显(两者都同样有用)。这里简单介绍下...原创 2019-09-01 11:39:41 · 4460 阅读 · 0 评论 -
C++17之定义表达式求值顺序
许多代码库和c++书籍包含的代码直观的看起来貌似是有效的,但是严格地说,它们具有未定义的行为。一个例子是在一个字符串中查找和替换多个子字符串:例1:#include <iostream>#include <string>int main(void){ std::string s = "I heard it even works if you don't ...原创 2019-09-01 13:08:19 · 940 阅读 · 0 评论 -
C++17之整数列表初始化枚举
对于具有固定底层类型的枚举,因为c++ 17可以使用该类型的整数值直接初始化列表。1. 对于普通枚举类型制定底层类型的普通枚举可以通过{integer_value}直接初始化:// unscoped enum with underlying type:enum MyInt : char { };MyInt i1{42}; // OK since C++17 (ERROR befo...原创 2019-09-01 15:10:51 · 1322 阅读 · 0 评论 -
C++17之修复对auto的列表初始化
在c++ 11中引入带花括号的统一初始化之后,我们发现在使用auto而不是特定类型时,不幸的是存在一些不直观的不一致性://g++ 7.11int x{42}; // initializes an intint y{1,2,3}; // ERRORauto a{42}; // OK: initializes an int auto b{1,2,3};//error: direct-l...原创 2019-09-01 15:55:42 · 945 阅读 · 0 评论 -
C++17之noexcept作为类型的一部分
在c++ 17异常处理规范成为函数类型的一部分。也就是说,下面两个函数现在有两种不同的类型:void f1();void f2() noexcept; // different type在c++ 17之前,这两个函数都具有相同的类型。因此,编译器现在将检测如果你使用一个函数抛出异常,而一个函数不抛出任何异常的情况:void (*fp)() noexcept; // pointe...原创 2019-09-01 16:58:42 · 1436 阅读 · 0 评论 -
C++17之只接受一个参数的static_assert
c++ 17,以前需要的static_assert()消息参数现在是可选的。意味着static_assert声明不再需要第二个参数。例如:#include <type_traits>template<typename T>class C {// OK since C++11:static_assert(std::is_default_constructibl...原创 2019-09-01 17:02:50 · 904 阅读 · 0 评论 -
C++17之预处理条件__has_include
c++ 17扩展了预处理器,使其能够检查是否包含特定的头文件。例如:#if __has_include(<filesystem>)# include <filesystem># define HAS_FILESYSTEM 1#elif __has_include(<experimental/filesystem>)# include <ex...原创 2019-09-01 17:09:08 · 4312 阅读 · 0 评论 -
c++17之 if和switch语句中初始化变量
从C++17开始,if和switch控制结构现在允许我们在条件语句或选择子句旁边指定一个初始化子句。例如:if (int result = getResult(); result != -1){//do something}//result 变量的有效范围到此为止。1. 首先介绍下if判断语句中变量的初始化在if语句中初始化的任何值在then和else部分结束之前都是...原创 2019-08-25 16:58:21 · 3999 阅读 · 0 评论