Код: Выделить всё
#include
// compile-time count of "{}" inside "str"
consteval int count_occurrences(std::string_view str) {
int count = 0;
size_t pos = 0;
std::string_view pattern("{}");
while ((pos = str.find(pattern, pos)) != std::string_view::npos) {
++count;
pos += pattern.length();
}
return count;
}
template
struct FormatStringImpl {
template
consteval FormatStringImpl(Str const& str) : frmt(str) {
// frmt is not considered as a constant expression so the next line
// obviously doesn't compile
auto constexpr n = count_occurrences(frmt);
static_assert(sizeof...(Args) >= n, "wrong number of arguments");
}
std::string_view frmt;
};
// don't try to deduce Args from FormatString in foo call
template
using FormatString = FormatStringImpl;
template
consteval void foo([[maybe_unused]] FormatString const frmt,
[[maybe_unused]] Args&&... args) {};
The general idea is to perform the check during compile-time construction of the argument frmt (and not inside foo where none input argument could be used inside a constant evaluated expression).
Another trick is to make the format string type dependent on the types of the other arguments of foo (and not there values).
Теперь я застрял, потому что я не вижу, как продолжить чек внутри конструктора. Моя попытка, очевидно, терпит неудачу, потому что я пытаюсь инициализировать выражение времени компиляции из формально неизвестного выражения. Глядя на реализацию STL, быстро теряет меня в деталях, которые мешают мне получить основные идеи (которые я мог бы повторно использовать с помощью более подробных проверок). < /P>
Я нашел возможное решение из этого другого ответа: < /p>
< /p>
Подробнее здесь: https://stackoverflow.com/questions/796 ... -compile-t
Мобильная версия