Передача объектов constexpr вокруг

Я решил дать тогда новый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 ++ Сейчас 2012 в версии, измененной дляC++14.

Приведенный выше код не скомпилируется с ошибкой (clang-3.5)

error: constexpr variable 'nOpen' must be initialized by a constant expression  
    constexpr auto nOpen = numOpen( str );  
                           ~~~~~~~~~^~~~~

Что приводит меня к выводу, что вы не можете обойтиconstexpr объект, не теряя своегоconstexpr-ness. Это привело меня к следующим вопросам:

Правильна ли моя интерпретация?

Почему такое поведение предписывает стандарт?

Я не вижу проблемы в прохожденииconstexpr объект вокруг. Конечно, я мог бы переписать свой код, чтобы он поместился в одну функцию, но это приводит к ограниченному коду. Я бы предположил, что разделение отдельных функций на отдельные блоки кода (функции) должно быть хорошим стилем и для операций времени компиляции.

Как я уже говорил, ошибку компилятора можно устранить, перемещая код из тел отдельных функций тестирования (таких какnumOpenв теловерхний уровень функцияcheck, Однако мне не нравится это решение, поскольку оно создает одну огромную и тесную функцию. Видите ли вы другой подход к решению проблемы?

Ответы на вопрос(1)

Ваш ответ на вопрос