strlen()编译时优化

Nic*_*ick 7 c++ arrays string c++11

几天前我发现你可以strlen使用这样的东西找到编译时间:

template<size_t N>
constexpr size_t strlen_(const char (&data)[N]) noexcept{
    return N - 1;
}
Run Code Online (Sandbox Code Playgroud)

如果它被编译,那么一切都很好.你可以添加这样的重载:

size_t strlen_(const char *s) noexcept{
    return strlen(s);
}
Run Code Online (Sandbox Code Playgroud)

然后它将始终编译.

我的问题是 - C++是否<cstring>使用了这样的东西,如果没有 - 为什么?

Ben*_*ley 9

不,它没有.因为它给出了错误的答案.

char x[10] = "abc";
int correct_length   = std::strlen(x);  // 3
int incorrect_length = strlen_(x);      // 9
Run Code Online (Sandbox Code Playgroud)

此外,对于2次重载,将永远不会调用模板.接受a的非模板const char*将始终是首选.

这并不意味着在编译时无法使用某些编译器魔法来计算strlen.但是,使用正确的语言不能这样做.

  • @Soren:两个帐户都错了. (3认同)

The*_*ign 5

strlen_将返回 array 的大小data,而不是以空字符结尾的字符串的大小。正确的实现是:

constexpr size_t ct_strlen( const char* s ) noexcept
{
  return *s ? 1 + ct_strlen(s + 1) : 0;
}
Run Code Online (Sandbox Code Playgroud)


Non*_*upt 3

你的代码有问题。

令人惊讶的是,进行编译时优化的正确方法strlen()是直接调用strlen(). strlen()像 clang 这样的现代编译器在编译时知道长度时会优化掉不必要的东西。

此外,在大多数情况sizeof下,当您(程序员)将它与保存文字字符串的变量正确使用时,它会派上用场。喜欢:

const char foo[] = "Hello World";
size_t len = sizeof(foo)-1; // 11
Run Code Online (Sandbox Code Playgroud)

请注意,这有一些假设,如果你这样做,你会给自己带来麻烦,但不会让你的生活变得简单:

const char foo[] = "Hello World\01234";
size_t len = sizeof(foo)-1; // 16
Run Code Online (Sandbox Code Playgroud)

编辑:让显而易见的事情看起来更像是一个答案。