首页 > 科技 > C++ 20中的explicit(bool)介绍

C++ 20中的explicit(bool)介绍

一句话开头

explicit(bool)是C++ 20中的一个特性,这个特性用于检查通用类型的实现并且可以减少编译时间。

细说explicit(bool)

在C++中,通过将对象封装成其他类型的技法十分常见,例如std::pair和std::optional就是两个十分典型的例子。并且,在C++标准库,Boost或者你自己的代码库中,我们还可以看到许多类似的使用。遵循”Principle of least astonishment”原则,我们可以确保封装器能尽量的保持被封装对象的特性。

让我们以std::string来举个栗子,我们可以提供一个字符串字面值来构造std::string对象,但是我们不可以从一个std::string_view中构造它。如下图所示:

通过将std::string的构造函数声明为一个接受std::string_view的显式构造,我们就可以实现这个想法。

如果你正在编写一个封装器,那么在很多情况下,我们都希望能暴露被封装对象的相同特性。例如,如果被封装对象能支持隐式类型转换,则我们的封装器也应该支持这个特性。如果被封装对象不支持某个特性,那么,封装器也不应该支持这个特性。具体来说:

实现这个的普遍方法时使用SFINAE(Substitution Failure Is Not An Error)。如果我们编写了如下图所示的一个封装器:

我们可以将单一的构造函数替换为两个重载的版本:一个是隐式构造版本,它处理当u可以被隐式转换为T的情况,另一个版本是一个显式构造版本,它可以处理第一个版本不能处理的情况,如下图所示:

这个修改,可以实现我们想要的行为。但是,它并不能让人十分满意:我们需要定义两个重载的版本,但是实际应该只需要一个版本。另外,我们还需要使用SFINAE来从这两个版本中进行选择,这意味着它将增加编译时间,并降低代码的清晰度。

使用explicit(bool),可以解决上述问题。它可以允许我们将条件式的转换集成到显式的声明中。例如:

当下一次你希望能条件式的显式声明时,可以使用explicit(bool)来实现。这个方法可以简化代码,减少编译时间并去除程序中重复的部分。

explicit(bool)将会在MSVC v14.24(其在VS2019 version 16.4中可用),Clang 9和GCC 9中被支持。欢迎下载VS2019进行体验。

另外,还有几点

1. 我明白,隐式类型转换经常会导致一些奇奇怪怪的问题。但是在某些场景下,它们也有一些好处,例如它可以提升编译效率并且将选择权留给用户,这样使得通用类型将变得更加易用。

2. 本文中,我忽略了有关std::forward及其相关的内容,主要是为了是本文尽量简化。

3. 在一次测试中,我测试了500次泛型实例化,发现使用explicit(bool)更提升编译前端效率达15%左右。

4. 在VS2019 v16.2中,我们可以使用编译选项/permissive-来支持这个特性,但是在某些构建中,如果没有指定这个选项,就可能会有一些问题。

总结

对泛型的理解,一直是我心中的痛。关键是,我的工作中,还真是比较少用这玩意。还是老老实实的写C with classes保平安吧。

GCC

本文来自投稿,不代表本人立场,如若转载,请注明出处:http://www.souzhinan.com/kj/213407.html