Я придумал следующее:
Код: Выделить всё
#include
#include
#include
// Dummy counts characters, not placeholders.
consteval std::size_t countPlaceholdersDummy(const auto formatString) {
std::size_t count = 0;
while (formatString[count] != '\0') ++count;
return count;
}
template
class strictFormatString {
public:
const std::format_string formatString;
consteval strictFormatString(const auto formatString)
: formatString(formatString) {
constexpr std::size_t expected = sizeof...(Args);
constexpr std::size_t actual = countPlaceholdersDummy(formatString);
static_assert(
actual == expected,
"Number of arguments must exactly match number of placeholders");
}
};
template
auto strictFormat(strictFormatString fmt,
Args&&... args) {
return std::format(fmt.formatString, std::forward(args)...);
}
int main() { strictFormat(""); }
(22): ошибка C2131: выражение не получило константу
(19): примечание: сбой был вызван чтением переменной за пределами ее срока службы
(19): примечание: см. использование 'formatString'
Как это исправить - не прибегая к макросам? В идеале, strictFormatString должен оставаться в коде, поскольку я использую его и для других целей (например, для захвата std::source_location вызывающего объекта).
Подробнее здесь: https://stackoverflow.com/questions/798 ... a-argument
Мобильная версия