Я решил дать тогда новое C++14
определение constexpr
a spin и, чтобы получить максимальную отдачу от него, я решил написать небольшой синтаксический анализатор строк компиляции. Тем не менее, я борюсь с тем, чтобы сохранить объект 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);
}
I использует str_const
class представленный Scott Schurr at 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
-ness. Это привело меня к следующим вопросам:
- Является ли моя интерпретация правильной?
Почему это поведение соответствует стандарту?
Я не вижу проблемы с передачей объекта
constexpr
. Конечно, я мог бы переписать мой код, чтобы вписаться в одну функцию, но это приводит к тесному коду. Я бы предположил, что факторинг отдельных функций в отдельные единицы кода (функции) должен быть хорошим стилем для операций времени компиляции.- Как я уже говорил ошибка компилятора может быть решен путем перемещения кода из тел отдельных функций тестирования (например,
numOpen
) в тело функцииверхнего уровняcheck
. Однако мне не нравится это решение, поскольку оно создает одну огромную и ограниченную функцию. Вы видите другой подход к решению проблемы?
* Вы видите другой подход к решению проблемы? * 'Constexpr auto nOpen = numOpen (str);' экземпляр не должен быть 'constexpr' для оценки функции во время компиляции –