我刚刚注意到 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/