【问题标题】:How to printf std::vector<>::size_type?如何打印 std::vector<>::size_type?
【发布时间】:2020-10-11 09:32:02
【问题描述】:

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

【问题讨论】:

  • 如何找到?阅读文档,使用 google 等。C++11 及更高版本的%z 格式对应于std::size_t(就像在C99 和更高版本中的%z 对应于size_t)。严格来说,std::vector::size_type 是否与std::size_t 相同是实现定义的,但我还没有遇到不是的实现。在 C++11(和 C99)之前,必须在检查值在范围内之后转换为另一种整数类型(如 long unsigned)。实际上,在 C++ 中,最好使用 C++ 流(通过函数重载正确处理 size_t
  • 一种选择是转换为uintmax_tstd::size_t(不确定它是否足以容纳std::vector::size_type)。
  • @Peter 感谢您提供的信息和建议的解决方法。
  • @Peter 这是%zu
  • @Bob__ 我更改了欺骗目标。现在看起来是正确的。

标签: c++ printf c++14 std


【解决方案1】:

它的 printf 格式说明符是什么?

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

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

分步:

  1. 创建一个库以根据类型获取printf 格式说明符。
  2. 在该类型上模板化该库。

这与std::cout::operator&lt;&lt; 重载用于打印的方式相同。只是:

#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));
}

【讨论】:

    【解决方案2】:

    一个不起眼的实用技巧

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

    1. 尽可能找到最大(按大小)有符号和无符号整数类型的 printf 格式说明符。
    2. 在编译时,使用std::is_signed_t&lt;T&gt; 确定向量size_type 的符号。
    3. 在运行时,检查大小值是否足够小以适合目标类型,否则仅声明失败。
    4. size_type 转换为适当的整数类型。
    5. 您现在可以在 printf 调用中使用强制转换值。

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

    【讨论】:

      【解决方案3】:

      printf 中使用的选项是%zu

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

      【讨论】:

      猜你喜欢
      • 2017-12-23
      • 1970-01-01
      • 2020-03-06
      • 2021-01-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-14
      • 1970-01-01
      相关资源
      最近更新 更多