在编译时检查字符串文本的长度

Check length of string literal at compile time

本文关键字:文本 字符串 编译 检查      更新时间:2023-10-16

我想在编译时检查字符串文字的长度。现在我正在考虑以下构造,但无法完成:

#define STR(s) (sizeof(s) < 10 ? s : /* somehow perform static_assert */)
void foo(const char* s) {}
int main() { 
foo(STR("abc")); // foo("abc")
foo(STR("abcabcabcabc")); // compile time error: "String exceeds 10 bytes!"
}

>这是C++,其中有优于宏的选项。模板可以为您提供所需的确切语义。

template<std::size_t N>
constexpr auto& STR(char const (&s)[N]) {
static_assert(N < 10, "String exceeds 10 bytes!");
// < 11 if you meant 10 characters. There is a trailing ``
// in every literal, even if we don't explicitly specify it
return s;
}

数组引用参数将绑定到字符串文本,而不是指针(可能会触发宏(,推断它们的大小,并在函数主体中执行检查。然后,如果所有内容都检出,它将返回引用不变,甚至允许继续解决过载问题。

我会添加到@StoryTeller - 不诽谤莫妮卡伟大的答案, 如果你需要(像我一样(传递字符串的最大长度和参数,你可以将实现扩展为更通用的:

template<const int MAX_LEN, std::size_t N>
constexpr auto& STR(char const (&s)[N]) 
{
static_assert(N < MAX_LEN, "String overflow!");
return s;
}

如果您需要几个已知长度,您可以使用模板专用化:

template<std::size_t N>
constexpr auto & STR16(char const (&s)[N])
{
return STR<16>(s);
}

第一个函数可以是通用版本,第二个函数可以访问项目的常量。