许多开发人员和库作者多年来一直在为编译时字符串而苦苦挣扎 - 因为标准(库)字符串std::string
需要动态内存分配,而不是constexpr。
所以我们有很多关于如何正确编译时字符串的问题和博客文章:
- 方便地在C++中声明编译时字符串 在编译时连接
- 模板中的编译时字符串?
- C++ 编译时字符串操作
- (异地)使用 constexpr 编译时字符串
我们现在了解到,不仅new
在constexpr
代码中可用,允许在编译时进行动态分配,而且事实上,std::string
将在 C++20 中成为 constexpr(C++ Herb Sutter 的标准工作组会议报告)。
这是否意味着对于 C++20 及以上的代码,我们应该丢弃所有这些漂亮的编译时字符串实现,并始终使用std::string
?
如果没有 - 我们什么时候会这样做,我们什么时候会坚持今天可能的东西(当然除了向后兼容的代码)?
注意:我不是在谈论其内容是其类型一部分的字符串,即不谈论相当于std::integral_constant
;这绝对不会std::string
。
这取决于你所说的"constexpr string"是什么意思。
C++20 允许您做的是在标记为constexpr
(或consteval
)的函数中使用std::string
。 这样的函数可以创建一个string
,操作它,等等,就像任何文字类型一样。但是,该字符串不能泄漏到非constexpr
代码中;这将是非瞬态分配,是被禁止的。
问题是,您给出的所有示例都是尝试使用字符串作为模板参数。这是一件相似但又不同的事情。您不只是在谈论在编译时构建字符串;现在,您希望使用它来实例化模板。
C++20 通过允许用户定义类型作为模板参数来解决此问题。但是对此类类型的要求比仅仅是文字类型要严格得多。该类型不得具有非公共数据成员,并且唯一的成员是遵循这些限制的类型。基本上,编译器需要知道其数据成员的逐字节比较表示等效值。即使是具有constexpr
能力的std::string
也不是这样工作的。
但std::array<char, N>
可以做到这一点。如果您在constexpr
代码中,请调用返回std::string
的constexpr
函数,并将该字符串存储在constexpr
值中,则string::size()
是一个constexpr
函数。因此,您可以使用它来填充数组的N
。
将字符复制到constexpr array
(因为它是constexpr
值,所以它是不可变的)有点复杂,但它是可行的。
所以 C++20 解决了这些问题,只是不是(直接)用std::string
.