J’ai décidé de constexpr
ensuite la nouvelle définition de constexpr
C++14
et d’en tirer le meilleur parti, j’ai décidé d’écrire un petit parsingur de chaîne au moment de la compilation. Cependant, j’ai du mal à garder mon object comme constexpr
tout en le passant à une fonction. Considérons le code suivant:
#include #include class str_const { const char * const p_; const std::size_t sz_; public: template constexpr str_const( const char( & a )[ N ] ) : p_( a ), sz_( N - 1 ) {} constexpr char operator[]( std::size_t n ) const { return n < sz_ ? p_[ n ] : throw std::out_of_range( "" ); } constexpr std::size_t size() const { return sz_; } }; constexpr long int numOpen( const str_const & str ){ long int numOpen{ 0 }; std::size_t idx{ 0 }; while ( idx < str.size() ){ if ( str[ idx ] == '{' ){ ++numOpen; } else if ( str[ idx ] == '}' ){ --numOpen; } ++idx; } return numOpen; } constexpr bool check( const str_const & str ){ constexpr auto nOpen = numOpen( str ); // ... // Apply More Test functions here, // each returning a variable encoding the correctness of the input // ... return ( nOpen == 0 /* && ... Test the variables ... */ ); } int main() { constexpr str_const s1{ "{ Foo : Bar } { Quooz : Baz }" }; constexpr auto pass = check( s1 ); }
J’utilise la classe str_const
présentée par Scott Schurr à C ++ Now 2012 dans une version modifiée pour C++14
.
Le code ci-dessus ne pourra pas être compilé avec l’erreur ( clang-3.5
)
error: constexpr variable 'nOpen' must be initialized by a constant expression constexpr auto nOpen = numOpen( str ); ~~~~~~~~~^~~~~
Ce qui m’amène à la conclusion que vous ne pouvez pas contourner un object constexpr
sans perdre son constexpr
constexpr. Cela m’a amené aux questions suivantes:
Pourquoi est-ce le comportement que la norme dicte?
Je ne vois pas le problème en passant un object constexpr
autour. Bien sûr, je pourrais réécrire mon code pour l’intégrer à une seule fonction, mais cela conduit à un code exigu. Je suppose que la factorisation de fonctionnalités distinctes dans des unités de code (fonctions) distinctes devrait également constituer un bon style pour les opérations de compilation.
numOpen
) dans le corps de la check
fonction de niveau supérieur. Cependant, je n’aime pas cette solution car elle crée une fonction énorme et exiguë. Voyez-vous une approche différente pour résoudre le problème? La raison en est que, dans une fonction constexpr
, les parameters ne sont pas des expressions constantes , que les arguments soient ou non. Vous pouvez appeler des fonctions constexpr
l’intérieur d’autres personnes, mais les parameters d’une fonction constexpr
ne sont pas constexpr
intérieur , rendant tout appel de fonction (même aux fonctions constexpr
) pas une expression constante – à l’ intérieur .
const auto nOpen = numOpen( str );
Suffices Une fois que vous visualisez l’appel de l’ extérieur de la constexpr
-ness des expressions à l’intérieur, il est vérifié, décidant si l’appel entier est constexpr
ou non.