如何打印std::vector<>::size_type?

How to printf std::vector<>::size_type?

std::vector 具有成员类型 size_type。它的 printf 格式说明符是什么?

请注意 size_typesize_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 中使用的选项是 %zu

这是从 C99 开始使用的。在您需要将类型转换为 unsigned long.

之前

What is its printf format specifier?

没有人知道。没有具体说明 std::vector<?>::size_type 到底是什么,除了它是一个“无符号整数类型”int C++ Container Library, General container requirements。因为 printf 格式说明符取决于类型,所以这一切都取决于特定的实现。也可能不存在 printf 格式说明符。

How to printf std::vector<>::size_type?

步骤:

  1. 创建库以根据类型获取 printf 格式说明符。
  2. 将该库作为该类型的模板。

这与 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));
}

一个不起眼的实用技巧

似乎没有像其他答案所建议的那样优雅、直接的方法来做到这一点。那怎么办?由于缺乏更好的方法,让我们谦虚地回归基础:

  1. 查找最大 (size-wise) 有符号和无符号整数类型的 printf 格式说明符。
  2. 在 compile-time,使用 std::is_signed_t<T>.
  3. 确定向量 size_type 的符号
  4. 在run-time,检查大小值是否足够小以适合目标类型,否则就宣告失败。
  5. size_type 转换为适当的整数类型。
  6. 您现在可以在 printf 调用中使用转换值。

PS - 要在 signed/unsigned 格式说明符之间进行选择,您需要动态构造格式字符串,或者在两个格式字符串之间进行选择,或者使用条件编译等。相反,您可以只选择最大的有符号类型并始终转换为 that - 代价是需要最后一位的最大尺寸失败。