获取常量char数组的字符串长度函数(strlen)不是常量表达式

SLN*_*SLN 6 c++ arrays constexpr

让我们直接看一下简化的代码(编译:GCC 6.3.0)

#include<iostream>
#include<cstring>

using namespace std;

int main(int arga, char* argv[]) {

    const char cs[] = "Hello";//define a constant c-style string 
    constexpr size_t newSize = strlen(cs) + strlen(" ");//Error

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译器产生错误: strlen(((const char*)(&cs)))不是常量表达式

但是,当我将c字符串定义移动到全局范围时,问题就会消失.

.... 
const char cs[] = "Hello";

int main(int arga, char* argv[]) {
    constexpr size_t newSize = strlen(cs) + strlen(" ")//No Error
 ....
}
Run Code Online (Sandbox Code Playgroud)

有人能解释发生了什么吗?为什么strlen()将全局定义的常量c-string视为常量表达式,而不是堆栈中的那个?

ere*_*non 6

因此,标准strlen不能constepxrconstexpr上下文中使用.但是,GCC 知道strlen,因此在某些情况下它能够计算字符串的长度 - 即使它没有被标准规定/允许.

如果您只关心数组,可以使用std :: size来获取它们的大小:

template <class T, std::size_t N>
constexpr std::size_t size(const T (&array)[N]) noexcept
{
    return N;
}
Run Code Online (Sandbox Code Playgroud)