const char* 不能用作 std::char_traits<char>::length 的常量值
const char* cannot be used as a constant value for std::char_traits<char>::length
我有以下代码:
constexpr uint32_t countWords(const char* str) {
constexpr std::size_t length = std::char_traits<char>::length(str);
std::uint32_t count = 0;
for (std::size_t i = 0; i < length; i++) {
if (str[i] == ' ') {
count++;
}
}
return count;
}
我的问题出现在函数的第一行,我收到一个语法错误,指出:
str cannot be used as a constant
当我尝试将其传递给 std::char_traits<char>::length
时。如果我从 length
变量中删除 constexpr,错误就会消失,但对我来说,这意味着该变量在编译时不可获得,这违背了 constexpr 函数的目的。我植物调用这个函数使用字符串文字作为参数。
首先,您需要让您的编译器知道长度将在编译时计算。使用您当前的实现, str
参数可以在编译时和运行时传递给函数调用(如果您不知道, constexpr
不强制在编译时执行,它可以在运行时也是如此;检查来自 C++20 的 consteval
,它强制编译时计算)。
因此,为了确保您的 str
变量在编译时被传递,您可能希望将其作为非类型模板参数传递,例如:
template <char const * S>
constexpr uint32_t countWords() {
constexpr std::size_t length = std::char_traits<char>::length(S);
std::uint32_t count = 0;
for (std::size_t i = 0; i < length; i++) {
if (S[i] == ' ') {
count++;
}
}
return count;
}
但是,请注意,如果您的 S
指针具有 static 存储,这将 仅 有效,因此以下将工作:
static constexpr char str[]{ "a b c" };
constexpr auto cnt = countWords<str>();
但以下 NOT 工作:
constexpr char str[]{ "a b c" };
constexpr auto cnt = countWords<str>(); // ERROR
更多信息,请参考这个问题。
除此之外,您的 countWords
函数没有做正确的事情,因为上面的示例会将变量 cnt
设置为不正确的值 2。
编辑:
如果您想对字符串文字使用函数,则其他答案描述了解决方法。
从评论来看,您似乎有兴趣在字符串文字上使用它。
要完成这项工作,您需要做的就是从 length
.
中删除 constexpr
该函数必须在 运行 时和编译时都可以调用。
但是当你用字符串文字调用它时,它可以在编译时计算出来。您可以通过将函数的 return 值分配给 constexpr
变量来验证这一点。
#include <iostream>
#include <string>
constexpr uint32_t countWords(const char* str) {
std::size_t length = std::char_traits<char>::length(str);
std::uint32_t count = 0;
for (std::size_t i = 0; i < length; i++) {
if (str[i] == ' ') {
count++;
}
}
return count;
}
int main()
{
constexpr auto wordcount = countWords("This is a sentence");
std::cout << wordcount;
}
我有以下代码:
constexpr uint32_t countWords(const char* str) {
constexpr std::size_t length = std::char_traits<char>::length(str);
std::uint32_t count = 0;
for (std::size_t i = 0; i < length; i++) {
if (str[i] == ' ') {
count++;
}
}
return count;
}
我的问题出现在函数的第一行,我收到一个语法错误,指出:
str cannot be used as a constant
当我尝试将其传递给 std::char_traits<char>::length
时。如果我从 length
变量中删除 constexpr,错误就会消失,但对我来说,这意味着该变量在编译时不可获得,这违背了 constexpr 函数的目的。我植物调用这个函数使用字符串文字作为参数。
首先,您需要让您的编译器知道长度将在编译时计算。使用您当前的实现, str
参数可以在编译时和运行时传递给函数调用(如果您不知道, constexpr
不强制在编译时执行,它可以在运行时也是如此;检查来自 C++20 的 consteval
,它强制编译时计算)。
因此,为了确保您的 str
变量在编译时被传递,您可能希望将其作为非类型模板参数传递,例如:
template <char const * S>
constexpr uint32_t countWords() {
constexpr std::size_t length = std::char_traits<char>::length(S);
std::uint32_t count = 0;
for (std::size_t i = 0; i < length; i++) {
if (S[i] == ' ') {
count++;
}
}
return count;
}
但是,请注意,如果您的 S
指针具有 static 存储,这将 仅 有效,因此以下将工作:
static constexpr char str[]{ "a b c" };
constexpr auto cnt = countWords<str>();
但以下 NOT 工作:
constexpr char str[]{ "a b c" };
constexpr auto cnt = countWords<str>(); // ERROR
更多信息,请参考这个问题
除此之外,您的 countWords
函数没有做正确的事情,因为上面的示例会将变量 cnt
设置为不正确的值 2。
编辑:
如果您想对字符串文字使用函数,则其他答案描述了解决方法。
从评论来看,您似乎有兴趣在字符串文字上使用它。
要完成这项工作,您需要做的就是从 length
.
constexpr
该函数必须在 运行 时和编译时都可以调用。
但是当你用字符串文字调用它时,它可以在编译时计算出来。您可以通过将函数的 return 值分配给 constexpr
变量来验证这一点。
#include <iostream>
#include <string>
constexpr uint32_t countWords(const char* str) {
std::size_t length = std::char_traits<char>::length(str);
std::uint32_t count = 0;
for (std::size_t i = 0; i < length; i++) {
if (str[i] == ' ') {
count++;
}
}
return count;
}
int main()
{
constexpr auto wordcount = countWords("This is a sentence");
std::cout << wordcount;
}