53 votes

C ++11 - static_assert dans la fonction constexpr?

Comment fait-on correctement un static_assert dans une fonction constexpr ? Par exemple:

 constexpr int do_something(int x)
{
  static_assert(x > 0, "x must be > 0");
  return x + 5;
}
 

Ce n'est pas du code C ++ 11 valide, car une fonction constexpr doit uniquement contenir une instruction return. Je ne pense pas que la norme fasse exception à cela, bien que GCC 4.7 ne me permette pas de compiler ce code.

60voto

Johannes Schaub - litb Points 256113

Ce n'est pas du code C ++ 11 valide, car une fonction constexpr doit uniquement contenir une instruction return.

Ceci est une erreur. static_assert dans une fonction constexpr vont bien. Ce qui ne va pas, c’est d’utiliser des paramètres de fonction dans des expressions constantes, comme vous le faites.

Vous pouvez lancer si x <= 0 . L'appel de la fonction dans un contexte nécessitant une expression constante échouera lors de la compilation

 constexpr int do_something(int x) {
  return x > 0 ? (x + 5) : (throw std::logic_error("x must be > 0"));
}
 

23voto

cppist Points 159

Cela fonctionne et est valide en C++11 code, parce que les arguments de modèle sont les temps de compilation uniquement:

template <int x>
constexpr int do_something() {
    static_assert(x > 0, "x must be > 0");
    return x + 5;
}

Je rencontre les mêmes problèmes que vous avez fait avec des expressions constantes en C++. Il y a quelques claire de la documentation sur constexprs pour le moment. Et notez qu'il y ait quelques bugs connus dans gcc est issue tracker, mais ton problème ne semble pas être un bug.

Notez que si vous déclarez constexpr des fonctions à l'intérieur des classes, vous n'êtes pas en mesure de les utiliser à l'intérieur de la classe. Cela semble également être pas un bug.

Edit: Ce qui est permis selon la norme: 7.1.3 unis

... ou un composé déclaration qui contient uniquement

  • null états,
  • static_assert-déclarations
  • typedef déclarations d'alias et les déclarations qui ne sont pas
    définir des classes ou des énumérations,
  • à l'aide de déclarations,
  • directives à l'aide,
  • et exactement une instruction de retour

-2voto

John Zwinck Points 43636

Est-ce que ça marche?

 constexpr int do_something(int x)
{
  return static_assert(x > 0, "x must be > 0"), (x + 5);
}
 

Je ne l'ai pas testé, mais c'est la seule chose qui me vienne à l'esprit, à part peut-être un abus de pré-processeur.

La théorie est que l'opérateur de virgule évalue son argument de gauche mais rejette le résultat et utilise comme résultat le résultat de son second argument.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X