简体   繁体   English

如何 printf std::vector<>::size_type?

[英]How to printf std::vector<>::size_type?

std::vector has a member type size_type . std::vector有一个成员类型size_type What is its printf format specifier?它的 printf 格式说明符是什么?

Note that size_type is not identical to size_t .请注意, size_typesize_t不同。
https://en.cppreference.com/w/cpp/container/vector https://en.cppreference.com/w/cpp/container/vector
https://en.cppreference.com/w/cpp/types/size_t https://en.cppreference.com/w/cpp/types/size_t
https://en.cppreference.com/w/cpp/io/c/fprintf https://en.cppreference.com/w/cpp/io/c/fprintf

What is its printf format specifier?它的 printf 格式说明符是什么?

No one knows.没人知道。 It's not specified what std::vector<?>::size_type exactly is, except that it is a "unsigned integer type" int C++ Container Library, General container requirements .它没有指定std::vector<?>::size_type到底是什么,除了它是一个“unsigned integer type”int C++ Container Library, General container requirements Because printf format specifier depends on the type, it all depends on particular implementation.因为printf格式说明符取决于类型,所以这一切都取决于特定的实现。 It may also be possible that there doesn't exists a printf format specifier.也可能不存在printf格式说明符。

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

In steps:步骤:

  1. Create a library to get printf formatting specifier depending on the type.创建一个库以根据类型获取printf格式说明符。
  2. Template that library on that type.该类型的库模板。

It's just the same as std::cout::operator<< overloads are doing for printing anyway.无论如何,它与std::cout::operator<<重载为打印所做的一样。 Just:只是:

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

A humble practical hack一个不起眼的实用技巧

There seems to be no elegant, straightforward way to do this, as other answers suggest.正如其他答案所建议的那样,似乎没有优雅、直接的方法来做到这一点。 What to do, then?那怎么办? For lack of a better approach, let's be humble and go back to basics:由于缺乏更好的方法,让我们谦虚 go 回到基础:

  1. Find printf format specifiers for the largest (size-wise) signed and unsigned integer types that you can.查找 printf 格式说明符,用于最大(按大小)有符号和无符号 integer 类型。
  2. At compile-time, determine the signedness of the vector size_type using std::is_signed_t<T> .在编译时,使用std::is_signed_t<T>确定向量size_type的符号。
  3. At run-time, check that the size value is small enough to fit into the target type, otherwise just declare failure.在运行时,检查大小值是否足够小以适合目标类型,否则就宣告失败。
  4. Cast the size_type to the appropriate integer type.size_type转换为适当的 integer 类型。
  5. You can now use the cast value in a printf call.您现在可以在 printf 调用中使用转换值。

PS - To choose between the signed/unsigned format specifiers, you will need to either construct the format string dynamically, or choose between two format strings, or use conditional compilation etc. Instead, you could just go for the largest signed type and always cast into that - at the price of failing for the largest sizes which need that last bit. PS - 要在有符号/无符号格式说明符之间进行选择,您需要动态构造格式字符串,或者在两个格式字符串之间进行选择,或者使用条件编译等。相反,对于最大的有符号类型,您可以只使用 go 并始终强制转换进入那个- 以需要最后一点的最大尺寸失败为代价。

The option to use in the printf is %zu .printf中使用的选项是%zu

This is used from C99.这是从 C99 使用的。 Before you need to cast the type to unsigned long .在您需要将类型转换为unsigned long之前。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM