Как разобрать статический const std :: string во время компиляции?

У меня есть несколько запросов SQL с привязками в моем коде C ++, эти запросы static const std::stringПоскольку эти запросы сложны, очень легко ошибиться с некоторыми деталями. Я хотел бы сделать некоторые очень простые проверки во время компиляции, например, подсчет количества запятых или : персонаж.

4

Решение

Ты не можешь static const std::string не существует во время компиляции.

Строковые литералы возможны с constexpr функции, но не std::string объекты.

5

Другие решения

std::string не существует во время компиляции. Если вы хотите иметь такое поведение, вы можете использовать строковые литералы с constexpr, как показано ниже:

constexpr const char* const var = "string";

Чтобы узнать больше об этом, пожалуйста, смотрите код сборки, сгенерированный для этого:

#include <string>

int main()
{
constexpr const char* const str = "string";
const std::string test = "test";
}

С X86-64 Clang 6.0.0 компилятор и с 0 оптимизаций,

constexpr const char* const str = "string";

сгенерированный ниже код:

subq    $80, %rsp
movq    $.L.str, -8(%rbp)
leaq    -48(%rbp), %rax

.L.str:
.asciz  "string"

и для const std::string test = "test"; код ниже генерируется (просто фрагмент)
Так он называет std::allocater который выделяет память в куче, а затем создает строковый объект.

        movq    %rax, %rdi
movq    %rax, -72(%rbp)         # 8-byte Spill
callq   std::allocator<char>::allocator() [complete object constructor]
movl    $.L.str.1, %ecx
movl    %ecx, %esi
leaq    -40(%rbp), %rdi
movq    -72(%rbp), %rdx         # 8-byte Reload
callq   std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&)
jmp     .LBB0_1
2

Вы не можете разобрать std::string во время компиляции, потому что он может быть создан только во время выполнения. Но в StackOverflow есть хорошие ответы, которые описывают, как определять и обрабатывать строки во время компиляции:

  1. Шифрование строки времени компиляции с использованием constexpr.
  2. Удобное объявление строк времени компиляции в C ++

Они относятся к Скотт Шурр str_const начиная со страницы 29:

class str_const { // constexpr string
private:
const char* const p_;
const std::size_t sz_;
public:
template<std::size_t N>
constexpr str_const(const char(&a)[N]) : // ctor
p_(a), sz_(N-1) {}
constexpr char operator[](std::size_t n) { // []
return n < sz_ ? p_[n] : throw std::out_of_range("");
}
constexpr std::size_t size() { return sz_; } // size()
};

Смотри как Contexpr JSON парсер JSON работает. Он способен анализировать всю строку JSON во время компиляции, поэтому должна быть возможность анализировать и проверять SQL во время компиляции. Для этого вам просто нужно использовать std_const Скотта или static_string Джейсона.

Вот тривиальное расширение, которое заставляет его играть лучше std::string_viewи иметь время компиляции substr метод:

class str_const {
private:
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 str_const(const std::string_view & sv) :
p_(sv.begin()), sz_(sv.size()) {}
constexpr operator std::string_view() const
{ return {p_, sz_}; }

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_; } // size()
constexpr const char*c_str() const { return p_; }

constexpr const char*begin() const { return p_; }
constexpr const char*end() const { return p_ + sz_; }
constexpr str_const substr(unsigned from, unsigned size) const
{
return from+size <= sz_ ? std::string_view{p_ + from, size} : throw std::out_of_range("");
}
};
std::ostream & operator<<(std::ostream& out, str_const str) {
return out << std::string_view(str);
}
2

Как уже говорил Себастьян, вы не можете, если вам нужно std::string, Но, возможно, в качестве альтернативы, вы можете сделать что-то вроде constexpr auto query = "MY SQL QUERY"; Я не знаю, разрешено ли вам изменять тип запросов.
Затем во время выполнения, query может быть использован для построения std::string если вам нужно. Проверки во время компиляции также могут быть сделаны.

Недостатком, конечно, является то, что он копируется во время выполнения при создании std :: string.

0
По вопросам рекламы [email protected]