c++ - 为什么 <cstring> 中的所有函数都不能有 constexpr?

标签 c++ constexpr c++17

我刚刚注意到 D0202R2建议所有<cstring>函数不得constexpr .我想了解为什么在 jackson 维尔 session 期间决定采用这样的解决方案。

采用类似 std::strchr 的函数.我真的看不出有什么理由不使用 constexpr。事实上,编译器可以很容易地优化一些 dummy code like this在编译时(即使我删除了内置函数,正如您从参数中看到的那样)。但是,与此同时,不可能在 constexpr 上下文中依赖这些函数或使用静态断言。

我们显然可以重新实现一些 <cstring>函数是 constexpr(就像我在 this other dummy code 中所做的那样),但我不明白为什么他们不能有 constexpr在标准库中。

我错过了什么?


附言:内置!

一开始我很困惑,因为 constexpr 函数使用了一些 <cstring>功能刚刚工作,然后我明白这只是由于 GCC 内置。实际上,如果您添加 -fno-builtin参数,你可以只使用std::strlen而不是函数的自定义版本。

最佳答案

更多地回顾这一点,并更多地思考 C++14 放宽围绕 constexpr 的规则的含义,我有不同的答案。

<cstring> header 是一堆 C 函数的包装器。 C没有constexpr概念,虽然拥有一个可能对它有用,但它不太可能很快发展起来。因此,以这种方式标记这些功能会很麻烦,并且需要很多 #ifdef

此外(我认为这是最重要的原因)当这些函数不是编译器内部函数时,它们是用 C 语言实现的,并作为目标代码存储在库文件中。库中的目标代码不是 C++ 编译器可访问的形式,无法在编译时求值。它们不像模板代码那样“内联”。

最后,他们所做的大部分真正有用的事情都可以很容易地用 C++ 实现 <algorithm>图书馆。 strlen(s) = (::std::string_view(s)).length() , memcpy(a, b, len) = ::std::copy(b, b + len, a)等等。和 D0202R2建议制作这些算法 constexpr .而且,正如您所指出的,它还建议在 ::std::string_view 中创建函数constexpr这些也提供了等效的功能。因此,考虑到前面提到的令人头疼的问题,似乎实现 constexpr对于 <cstring>功能将带来可疑的好处。

作为旁注,有 ::std::copy , ::std::move , ::std::copy_backward , 和 ::std::move_backward由您决定需要调用哪个。如果有一个函数可以计算出是否 x 就好了或 x_backward在那种特殊情况下需要像 memmove做。但是,由于迭代器的定义方式,将一个迭代器与另一个可能根本不迭代同一对象的迭代器进行比较在 C++ 中是不可能的,即使它们是随机访问迭代器也是如此。

关于c++ - 为什么 <cstring> 中的所有函数都不能有 constexpr?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42352114/

相关文章:

c++ - (重新)命名 std::pair 成员

c++ - 特定于类的释放函数可以在常量表达式中使用吗?

c++ - 为什么我们需要两个定义: integral constant expression and converted constant expression?

c++ - C++14 中的简单 constexpr LookUpTable

c++ - MSVC 中的折叠表达式

c++ - 为 sf::String 使用字符串文字时出现链接器错误

c++ - 将 DWORD_PTR 转换为类,反之亦然,无需 c 风格转换

c++ - 在 DirectX 中遇到拓扑问题

c++ - 指向 C++17 中 constexpr 静态成员的 constexpr 指针

c++ - 为什么模板化非常量参数构造函数优于给定的复制构造函数