Passando objetos constexpr ao redor
Eu decidi dar então novoC++14
definição deconstexpr
um giro e para tirar o máximo proveito dele, decidi escrever um pequeno analisador de string em tempo de compilação. No entanto, estou lutando para manter meu objetoconstexpr
enquanto passa para uma função. Considere o seguinte código:
#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 );
}
Eu uso ostr_const
classe apresentado porScott Schurr na C ++ Now 2012 em uma versão modificada paraC++14
.
O código acima falhará ao compilar com o erro (clang-3.5
)
error: constexpr variable 'nOpen' must be initialized by a constant expression
constexpr auto nOpen = numOpen( str );
~~~~~~~~~^~~~~
O que me leva à conclusão de que você não pode deixar passar umconstexpr
objeto sem perder suaconstexpr
-ness. Isso me levou às seguintes perguntas:
Por que esse é o comportamento que o padrão determina?
Não vejo problema em passar umconstexpr
objeto ao redor. Claro, eu poderia reescrever meu código para caber em uma única função, mas isso leva ao código restrito. Eu assumiria que fatorar a funcionalidade separada em unidades separadas de código (funções) também deve ser um bom estilo para operações em tempo de compilação.
numOpen
) no corpo donível superior funçãocheck
. No entanto, não gosto desta solução, pois cria uma função enorme e restrita. Você vê uma abordagem diferente para resolver o problema?