Как распечатать std :: vector <> :: size_type?
std::vectorимеет тип члена size_type. Каков его спецификатор формата printf?
Обратите внимание, что size_typeэто не идентично size_t.
https://en.cppreference.com/w/cpp/container/vector
https://en.cppreference.com/w/cpp/types/size_t
https://en.cppreference.com/w/cpp/io/c/fprintf
Ответы
Каков его спецификатор формата printf?
Никто не знает. Не указано, что std::vector<?>::size_typeименно, за исключением того, что это «целочисленный тип без знака» int Библиотека контейнеров C ++, Общие требования к контейнерам . Поскольку printfспецификатор формата зависит от типа, все зависит от конкретной реализации. Также возможно, что не существует printfспецификатора формата.
Как распечатать std :: vector <> :: size_type?
По шагам:
- Создайте библиотеку для получения
printfспецификатора форматирования в зависимости от типа. - Шаблон этой библиотеки для этого типа.
В std::cout::operator<<любом случае это то же самое, что и перегрузки для печати. Просто:
#include <cstdlib>
#include <string>
#include <cstdio>
#include <vector>
template<typename T> constexpr const char *get_printf_formatting_spec() noexcept;
template<> constexpr const char *get_printf_formatting_spec<std::size_t>() noexcept {
return "zu";
}
template<> constexpr const char *get_printf_formatting_spec<unsigned long long>() noexcept {
return "llu";
}
/// etc.
int main() {
const auto fmt = std::string() +
"%" +
get_printf_formatting_spec<std::vector<int>::size_type>() +
"\n";
std::printf(fmt.c_str(), static_cast<std::vector<int>::size_type>(1));
}
Скромный практический совет
Кажется, что нет элегантного и простого способа сделать это, как предполагают другие ответы. Что же тогда делать? Из-за отсутствия лучшего подхода давайте будем скромными и вернемся к основам:
- Найдите спецификаторы формата printf для самых больших (по размеру) целочисленных типов со знаком и без знака, которые вы можете.
- Во время компиляции определите подписанность вектора,
size_typeиспользуяstd::is_signed_t<T>. - Во время выполнения убедитесь, что значение размера достаточно мало, чтобы соответствовать целевому типу, в противном случае просто объявите сбой.
- Приведите
size_typeк соответствующему целочисленному типу. - Теперь вы можете использовать значение приведения в вызове printf.
PS - Чтобы выбрать между спецификаторами формата со знаком / без знака, вам нужно будет либо создать строку формата динамически, либо выбрать одну из двух строк формата, либо использовать условную компиляцию и т. Д. Вместо этого вы можете просто выбрать самый большой подписанный тип и всегда приводить в это - ценой неудачи для самых больших размеров, которым нужен последний бит.