首页 > 解决方案 > std::string 最终会成为我们的编译时字符串吗?

问题描述

许多开发人员和库作者多年来一直在为编译时字符串苦苦挣扎——因为标准(库)字符串std::string,需要动态内存分配,而不是 constexpr。

所以我们有很多关于如何正确获取编译时字符串的问题和博客文章:

我们现在了解到,它不仅new可以在constexpr代码中使用,允许在编译时进行动态分配,而且事实上,std::string它将成为 C++20 中的 constexpr(Herb Sutter 的 C++ 标准工作组会议报告)。

这是否意味着对于 C++20 及更高版本的代码,我们应该抛弃所有那些漂亮的编译时字符串实现并始终使用std::string?

如果不是 - 我们什么时候会这样做,我们什么时候会坚持今天的可能性(当然除了向后兼容的代码)?


注意:我不是在谈论内容是其类型的一部分的字符串,即不是在谈论相当于std::integral_constant; 那绝对不会std::string

标签: c++constexprstdstringidiomsc++20

解决方案


这取决于您所说的“constexpr string”是什么意思。

C++20 允许您做的是std::string在标记为constexpr(或consteval)的函数中使用。这样的函数可以像任何文字类型一样创建string、操作它等等。但是,该字符串不能泄漏到非constexpr代码中;这将是一个非瞬态分配,是被禁止的。

问题是,您提供的所有示例都是尝试使用字符串作为模板参数。这是一个相似但又不同的事情。您不只是在谈论在编译时构建字符串;你现在想用它来实例化一个模板。

C++20 通过允许用户定义的类型作为模板参数解决了这个问题。但是对这种类型的要求比仅仅作为文字类型要严格得多。该类型必须没有非公共数据成员,并且唯一的成员是遵循这些限制的类型。基本上,编译器需要知道其数据成员的逐字节比较代表一个等效值。甚至constexpr-capablestd::string也不能那样工作。

std::array<char, N> 做到。如果你在constexpr代码中,调用一个constexpr返回 a 的函数,std::string并将该字符串存储在一个constexpr值中,那么string::size()就是一个constexpr函数。所以你可以用它来填充N你的数组。

将字符复制到 a constexpr array(因为它是一个constexpr值,它是不可变的)有点复杂,但它是可行的。

所以 C++20 解决了这些问题,而不是(直接)使用std::string.


推荐阅读