Затем я решил опробовать новое C++14
определение constexpr
и, чтобы получить от него максимальную отдачу, я решил написать небольшой анализатор строк во время компиляции. Однако я изо всех сил пытаюсь сохранить свой объект constexpr
при передаче его функции. Рассмотрим следующий код:
#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 );
}
Я использую класс str_const
, представленный Скотт Шурр на C++Now 2012 в версии, модифицированной для C++14
.
Приведенный выше код не скомпилируется с ошибкой (clang-3.5
)
error: constexpr variable 'nOpen' must be initialized by a constant expression
constexpr auto nOpen = numOpen( str );
~~~~~~~~~^~~~~
Это приводит меня к выводу, что вы не можете обойти объект constexpr
, не потеряв при этом его constexpr
-ности. Это привело меня к следующим вопросам:
Верна ли моя интерпретация?
Почему это поведение диктует стандарт?
Я не вижу проблемы в передаче объекта
constexpr
. Конечно, я мог бы переписать свой код, чтобы он вписался в одну функцию, но это приводит к тесноте кода. Я бы предположил, что разложение отдельных функций на отдельные блоки кода (функции) также должно быть хорошим стилем для операций времени компиляции.Как я уже говорил, ошибку компилятора можно устранить, переместив код из тела отдельных функций тестирования (таких как
numOpen
) в тело функции верхнего уровняcheck
. Однако мне не нравится это решение, так как оно создает одну огромную и тесную функцию. Видите ли вы другой подход к решению проблемы?
constexpr auto nOpen = numOpen( str );
instance не обязательно должен бытьconstexpr
для оценки функции во время компиляции. - person Piotr Skotnicki   schedule 04.12.2014