我正试图编写一个函数“my_func()”,它在编译时计算字符串中“a”的字符数,这会使代码在“a”计数错误时无法编译。
我受到了这个功能的启发
std::format()
在C++标准库中,它检查
{}
格式字符串中。
我使用的编译器是msvc,C++20。
我下面的代码无法编译,因为我不知道如何实现这样的功能。那么我该如何修复函数
my_func()
?
template <size_t Size>
auto my_func(const char(&str)[Size]) -> void {
constexpr size_t count = 0;
const char* c = str;
for (size_t i = 0; i < Size; ++i) {
if (*c == 'a') {
count++;
}
c++;
}
static_assert(count == 2);
}
auto main() -> int {
my_func("abc abc");
}
下一个
感谢@ecatmur的回答,但我不知道如何在str转换为
counting_string
。
我尝试将构造函数的模板参数传递给类,但这使我在调用
prepare
作用
template <char Char, size_t Count, size_t Size>
struct counting_string {
std::array<char, Size> m_chars;
consteval explicit(false) counting_string(char const (&str)[Size]) {
size_t count = 0;
const char* c = str;
for (size_t i = 0; i < Size; ++i) {
if (*c == Char) {
count++;
}
c++;
}
if (count != Count) {
throw "invalid str";
}
}
};
template <size_t Size, class... Args>
auto prepare(const counting_string<'?', sizeof...(Args), Size> sql, Args... args) -> void {
}
auto main() -> int {
}
下面的代码是我希望实现的最终结果。
在没有额外开销(编译时检查)的情况下,检查SQL语句中占位符的数量以避免错误。
template <char Char, size_t Count>
struct constexpr_counting_string {
template <size_t Size>
consteval explicit(false) constexpr_counting_string(char const (&str)[Size]) {
size_t count = 0;
const char* c = str;
for (size_t i = 0; i < Size; ++i) {
if (*c == Char) {
count++;
}
c++;
}
if (count != Count) {
throw "invalid str";
}
}
};
template <typename... Args>
auto prepare(statement_t& stmt, constexpr_counting_string<'?', sizeof...(Args)> sql, Args... args) noexcept -> code_t {
code_t error = helper_prepare(stmt, sql);
auto do_bind = [](statement_t& stmt, size_t n, auto arg, code_t& error) noexcept {
if (error != code_t::ok) {
return;
}
using arg_type = decltype(arg);
if constexpr (std::is_same_v<arg_type, uint64_t>) {
error = stmt.bind(n, arg);
}
else if constexpr (std::is_same_v<arg_type, int64_t>) {
error = stmt.bind(n, arg);
}
else if constexpr (std::is_same_v<arg_type, int>) {
error = stmt.bind(n, arg);
}
else if constexpr (std::is_same_v<arg_type, const char*>) {
error = stmt.bind(n, arg);
}
else {
static_assert(std::is_same_v<arg_type, uint64_t>, "args error");
}
};
size_t index = 0;
(do_bind(stmt, index++, args, error), ...);
return error;
}
auto main() -> int {
prepare("insert into test (name, age) values (?, ?)", 1, 2);
}