Constexpr-Objekte umgeben
Ich habe beschlossen, dann neue @ zu gebC++14
Definition vonconstexpr
ein Dreh und um das Beste daraus zu machen, habe ich beschlossen, einen kleinen String-Parser zur Kompilierungszeit zu schreiben. Ich habe jedoch Probleme damit, mein Objekt als @ zu kennzeichneconstexpr
, während es an eine Funktion übergeben wird. Betrachten Sie den folgenden Code:
#include <cstddef>
#include <stdexcept>
class str_const {
const char * const p_;
const std::size_t sz_;
public:
template <std::size_t N>
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 );
}
Ich benutze dasstr_const
class präsentiert vonScott Schurr bei C ++ Now 2012 in einer für @ modifizierten VersiC++14
.
Der obige Code kann mit dem Fehler nicht kompiliert werden clang-3.5
)
error: constexpr variable 'nOpen' must be initialized by a constant expression
constexpr auto nOpen = numOpen( str );
~~~~~~~~~^~~~~
Was führt mich zu dem Schluss, dass man ein @ nicht umgehen kaconstexpr
Objekt ohne sein @ zu verlierconstexpr
-ness. Dies führte mich zu folgenden Fragen:
Warum ist dies das Verhalten, das der Standard vorschreibt?
Ich sehe das Problem nicht darin, ein @ zu übergebconstexpr
Objekt herum. Klar, ich könnte meinen Code so umschreiben, dass er in eine einzelne Funktion passt, aber das führt zu beengtem Code. Ich würde davon ausgehen, dass das Zerlegen separater Funktionen in separate Codeeinheiten (Funktionen) auch für Kompiliervorgänge eine gute Methode sein sollte.
numOpen
) in den Körper desHöchststuf functioncheck
. Diese Lösung gefällt mir jedoch nicht, da sie eine riesige und beengte Funktion erzeugt. Sehen Sie einen anderen Ansatz zur Lösung des Problems?