在编译时或至少在使用之前检查字符串是否包含禁止字符的任何创造性方法?
Any creative ways of checking if a string contains a forbidden character at compile time or at least before it's used?
我需要一种方法来验证常量字符串在编译时不包含特定字符。我考虑过使用 static_assert,但碰壁了,因为我尝试使用 .find 方法,它不是常量。
我可以选择在 class 的构造函数中进行检查(实例是上述 class 的 static const
成员)。
但在咬紧牙关之前(因为改变构造函数的行为有其他影响),我想看看是否有其他人有那些创造性的开箱即用的想法之一仍然可以完成这项工作,最好是在编译时。
By constant string 也许你的意思是 string literal,因为 std::string
不能用在常量表达式中。
在字符串文字的情况下,我们可以利用 constexpr
:(Live Demo)
template<int N>
constexpr bool has_forbidden_char(const char (&str) [N], char forbidden)
{
for(int i = 0; i < N; ++i)
{
if (str[i] == forbidden)
return true;
}
return false;
}
int main()
{
static_assert(!has_forbidden_char("foobar", 'x'));
static_assert(has_forbidden_char("foobar", 'f'));
}
编辑: 迭代到 N-1
如果您假设您将只接收字符串文字而不是任意字符数组。这样你就不会每次都检查 NULL 字符'\0'。 (C++ 中不存在零长度数组,所以不用担心索引为 -1)
//...
for(int i = 0; i < N-1; ++i){ //...
Edit2: 由于您使用的是 Visual Studio 2015,它没有放宽 constexpr
功能,这里有一个符合 C++11 的解决方案有效:
namespace detail {
template<int N>
constexpr bool has_forbidden_char_help(const char(&str)[N], char forbidden, int index)
{
return (index < N && (str[index] == forbidden || has_forbidden_char_help(str, forbidden, index+1)));
}
} // namespace detail
template<int N>
constexpr bool has_forbidden_char(const char (&str) [N], char forbidden)
{
return detail::has_forbidden_char_help(str, forbidden, 0);
}
int main()
{
static_assert(!has_forbidden_char("foobar", 'x'), "foobar doesn't have x, so this shouldn't fail...");
static_assert(has_forbidden_char("foobar", 'f'), "foobar does have f, so this shouldn't fail...");
}
我需要一种方法来验证常量字符串在编译时不包含特定字符。我考虑过使用 static_assert,但碰壁了,因为我尝试使用 .find 方法,它不是常量。
我可以选择在 class 的构造函数中进行检查(实例是上述 class 的 static const
成员)。
但在咬紧牙关之前(因为改变构造函数的行为有其他影响),我想看看是否有其他人有那些创造性的开箱即用的想法之一仍然可以完成这项工作,最好是在编译时。
By constant string 也许你的意思是 string literal,因为 std::string
不能用在常量表达式中。
在字符串文字的情况下,我们可以利用 constexpr
:(Live Demo)
template<int N>
constexpr bool has_forbidden_char(const char (&str) [N], char forbidden)
{
for(int i = 0; i < N; ++i)
{
if (str[i] == forbidden)
return true;
}
return false;
}
int main()
{
static_assert(!has_forbidden_char("foobar", 'x'));
static_assert(has_forbidden_char("foobar", 'f'));
}
编辑: 迭代到 N-1
如果您假设您将只接收字符串文字而不是任意字符数组。这样你就不会每次都检查 NULL 字符'\0'。 (C++ 中不存在零长度数组,所以不用担心索引为 -1)
//...
for(int i = 0; i < N-1; ++i){ //...
Edit2: 由于您使用的是 Visual Studio 2015,它没有放宽 constexpr
功能,这里有一个符合 C++11 的解决方案有效:
namespace detail {
template<int N>
constexpr bool has_forbidden_char_help(const char(&str)[N], char forbidden, int index)
{
return (index < N && (str[index] == forbidden || has_forbidden_char_help(str, forbidden, index+1)));
}
} // namespace detail
template<int N>
constexpr bool has_forbidden_char(const char (&str) [N], char forbidden)
{
return detail::has_forbidden_char_help(str, forbidden, 0);
}
int main()
{
static_assert(!has_forbidden_char("foobar", 'x'), "foobar doesn't have x, so this shouldn't fail...");
static_assert(has_forbidden_char("foobar", 'f'), "foobar does have f, so this shouldn't fail...");
}