Par chaîne constante peut-être vous dire un littéral chaîne , pour std::string
ne peut pas être utilisé dans une expression constante.
Dans la chaîne cas littérale, nous pouvons tirer profit de 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'));
}
Edit: itérer à N-1
si vous supposez que vous ne recevrez littéraux de chaîne et non pas des tableaux arbitraires de caractère . De cette façon, vous ne vérifierez pas le caractère NULL '\ 0' à chaque fois. (Tableaux de longueur nulle n'existent pas en C++, donc pas de soucis sur l'indexation à -1)
//...
for(int i = 0; i < N-1; ++i){ //...
Edit2: Puisque vous utilisez Visual Studio 2015, qui n'a pas constexpr
détendue fonctionnalité, voici une solution conforme C++ 11 qui fonctionne:
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...");
}
Vous pouvez utiliser la fonction constexpr de la chaîne C-littérale. Gcc a aussi une extension donc autorisez udl sur une chaîne littérale. – Jarod42
Spot sur! J'ai réussi à le faire fonctionner. Bien que je pense @AndyG réponse ci-dessous est plus lisible (marquage comme réponse pour aider les autres), voici ce que j'ai réussi à faire avec votre suggestion: –