当前位置:首页 >> 中医诊断 >> C++17在其业务代码中最好用的十个特性

C++17在其业务代码中最好用的十个特性

发布时间:2023-04-11

std::to_string(input) } // const char*和string顺利进行特殊处理 std::string convert(const char* input){ return input } std::string convert(std::string input){ return input } // c++17 template Simonlttypename T> std::string convert(T input) { if constexpr (std::is_same_vSimonltT, const char*> || std::is_same_vSimonltT, std::string>) { return input } else { return std::to_string(input) } } if初始化操作符

c++17拥护在if的推断操作符早先增加一个初始化操作符,将仅运用于if操作符内部的数据多种类型声明在if内,有助于大大提更高编码的可读性。且对于lock/iterator等牵涉到并发/RAII的多种类型更为容易确保程序的正确性。

// c++ 17 std::mapSimonltint, std::string> m std::mutex mx extern bool shared_flag // guarded by mx int demo { if (auto it = m.find(10) it != m.end) { return it-Simongtsecond.size } if (char buf[10] std::fgets(buf, 10, stdin)) { m[0] += buf } if (std::lock_guard lock(mx) shared_flag) { unsafe_ping shared_flag = false } if (int s int count = ReadBytesWithSignal(Simonamps)) { publish(count) raise(s) } if (const auto keywords = {Simonquotif", Simonquotfor", Simonquotwhile"} std::ranges::any_of(keywords, [Simonamptok](const char* kw) { return tok == kw })) { std::cerr << SimonquotToken must not be a keyword" } } 精度大大提更高 std::shared_mutex

shared_mutex是c++的原生读取锁解决问题,有协作和独占两种锁方式上,一般来说于并发更高的读情节下,通过reader早先协作锁来大大提更高精度。在c++17早先,只能自己通过独占锁和条件数据多种类型自己解决问题读取锁或可用c++14加入的精度较差的std::shared_timed_mutex。以下是通过shared_mutex解决问题的线程安全和计数器:

// c++17 class ThreadSafeCounter { public: ThreadSafeCounter = default // Multiple threads/readers can read the counterSimonaposs value at the same time. unsigned int get const { std::shared_lock lock(mutex_) return value_ } // Only one thread/writer can increment/write the counterSimonaposs value. unsigned int increment { std::unique_lock lock(mutex_) return ++value_ } // Only one thread/writer can reset/write the counterSimonaposs value. void reset { std::unique_lock lock(mutex_) value_ = 0 } private: mutable std::shared_mutex mutex_ unsigned int value_ = 0 } std::string_view

std::string_view原指是字段的“视图”,类小团体数据多种类型举例来说两个部分:字段所称针和字段较宽,std::string_view涵盖了std::string的所有可写接口。std::string_view对字段不兼具拥有权,且并行std::string和const char*两种多种类型。

c++17早先,我们处理可写字段常常可用const std::stringSimon,std::string有零点精度绝对优势:

并行两种字段多种类型,减少形参和内存扣除。如果传入的是下述字段const char*, const std::stringSimon无需顺利进行一次内存扣除,将字段光盘到砖头上,而std::string_view则可以意味著会。 在处理给定时,std::string::substr也无需顺利进行光盘和扣除内存,而std::string_view::substr则不无需,在处理大元数据解析时,精度绝对优势更为明显。 // from // author: Pavel Davydov // string_view的remove_prefix比const std::stringSimon的快了15倍 string remove_prefix(const string Simonampstr) { return str.substr(3) } string_view remove_prefix(string_view str) { str.remove_prefix(3) return str } static void BM_remove_prefix_string(benchmark::StateSimon state) { std::string example{Simonquotasfaghdfgsghasfasg3423rfgasdg"} while (state.KeepRunning) { auto res = remove_prefix(example) // auto res = remove_prefix(string_view(example)) for string_view if (res != Simonquotaghdfgsghasfasg3423rfgasdg") { throw std::runtime_error(Simonquotbad op") } } } std::map/unordered_map try_emplace

在向std::map/unordered_map中会插进要素时,我们常常可用emplace,emplace的反转是如果要素key不存有,则插进该要素,否则不插进。但是在要素已存有时,emplace仍意味著会结构一次待插进的要素,在推断不无需插进后,第一时间将该要素析构,因此顺利进行了一次多余结构和析构反转。c++17加入了try_emplace,意味著会了这个解决办法。同时try_emplace在参数此表中会将key和value分开,因此顺利进行原先结构的词汇比emplace更为加朴素

std::mapSimonltstd::string, std::string> m // emplace的原先结构无需可用std::piecewise_construct,因为是反之亦然插进std::pairSimonltkey, value> m.emplace(std::piecewise_construct, std::forward_as_tuple(Simonquotc"), std::forward_as_tuple(10, SimonaposcSimonapos)) // try_emplace可以反之亦然原先结构,因为参数此表中会key和value是分开的 m.try_emplace(Simonquotc", 10, SimonaposcSimonapos)

同时,c++17还给std::map/unordered_map加入了insert_or_assignformula_,可以更为有效率地解决问题插进或修改语义

多种类型的系统

c++17进一步完备了c++的多种类型的系统,终于加入了众望所归的多种类型插入容器(Type Erasure)和群论数据多种类型(Algebraic Data Type)

std::any

std::any是一个可以磁盘任何可光盘多种类型的容器,C词汇中会通常可用void*解决问题多种并不相同的机制,与void*相较,std::any兼具零点绝对优势:

std::any更为安全和:在多种类型T被反转成void*时,T的多种类型信息就早就丢失了,在反转回具体多种类型时程序不能推断当前的void*的多种类型是否知道是T,容易促使安全和隐患。而std::any意味著会磁盘多种类型信息,std::any_cast是一个安全和的形参。 std::any政府机构了并不一定的生命周期,在std::any析构时,意味著会将磁盘的并不一定析构,而void*则无需手动政府机构内存。

std::any应当很少是JavaScript的第一自由选择,在推断多种类型的情况下,std::optional, std::variant和继承都是比它更为更高效、更为合理的自由选择。只有当对多种类型完全未知的情况下,才应当可用std::any,比如动态多种类型文本的解析或者的业务演算的中会间层信息传递。

std::optional

std::optionalSimonltT>代表者一个意味著存有的T值,相同Haskell中会的Maybe和Rust/OCaml中会的option,实际上是一种Sum Type。常以于意味著挫败的formula_的常量中会,比如炼油厂formula_。在C++17早先,常常可用T*作为常量,如果为nullptr则代表者formula_挫败,否则T*所称向了或许的常量。但是这种寄给法模糊了拥有权,formula_的子程序方不能确定是否确实接管T*的内存政府机构,而且T*意味著为空的理论上,如果想起安全检查则意味著会有SegFault的可能性。

// pre c++17 ReturnType* func(const std::stringSimon in) { ReturnType* ret = new ReturnType if (in.size == 0) return nullptr // ... return ret } // c++17 更为安全和和恰当 std::optionalSimonltReturnType> func(const stringSimon in) { ReturnType ret if (in.size == 0) return nullopt // ... return ret } std::variant

std::variantSimonltT, U, ...>代表者一个多多种类型的容器,容器中会的值是制定多种类型的一种,是通用的Sum Type,相同Rust的enum。是一种多种类型安全和的union,所以也叫想到tagged union。与union相较有零点绝对优势:

可以磁盘比较简单多种类型,而union只能反之亦然磁盘系统化的POD多种类型,对于如std::vector和std::string就等比较简单多种类型则无需Gmail手动政府机构内存。 多种类型安全和,variant磁盘了内部的多种类型信息,所以可以顺利进行安全和的形参,c++17早先常常通过union+enum来解决问题相同机制。

通过可用std::variantSimonltT, Err>,Gmail可以解决问题多种并不相同Rust的std::result,即在formula_执行成功时来到结果,在挫败时来到错误信息,上文的例子则可以改成:

std::variantSimonltReturnType, Err> func(const stringSimon in) { ReturnType ret if (in.size == 0) return Err{Simonquotinput is empty"} // ... return {ret} }

无需注意的是,c++17只提供了一个库层次的variant解决问题,不会相同的方式上匹配(Pattern Matching)有助于,而最接近的std::visit又缺少解释器器的优化拥护,所以在c++17中会std::variant极为好用,跟Rust和formula_式词汇中会出神入化的Sum Type还相去甚远,但是早就有许多围绕std::variant的赞成被提交给c++委员意味著会探讨,举例来说方式上匹配,std::expected等等。

揭示一下,c++17新增的三种多种类型给c++促使了更为传统意义更为安全和的多种类型的系统,它们相同的可用情节是:

std::any一般来说于早先可用void*作为通用多种类型的情节。 std::optional一般来说于早先可用nullptr代表者挫败状态的情节。 std::variant一般来说于早先可用union的情节。 揭示

以上是说是在生产环境中会最常以的c++17适应性,除了本文刻画的十个适应性外,c++17还添加了如lambda值猎取*this, 钳夹formula_std::clamp, 强制安全检查常量[[nodiscard]]等更为易用的适应性,本文篇幅可用不想到赘述,瞩目有兴趣的读者自行探寻。

迪根和英太青的效果一样吗
多维元素片什么时候吃最好
拉肚子能用蒙脱石散吗
广东哪里有卖复方鳖甲软肝片
注射用胸腺法新有什么作用
友情链接: