Como imprimir std :: vector <> :: size_type?
std::vectortem um tipo de membro size_type. Qual é o seu especificador de formato printf?
Observe que size_typenão é idêntico a 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
Respostas
Qual é o seu especificador de formato printf?
Ninguém sabe. Não é especificado o que std::vector<?>::size_typeexatamente é, exceto que é um "tipo inteiro sem sinal" na Biblioteca de contêineres C ++, Requisitos gerais de contêiner . Como o printfespecificador de formato depende do tipo, tudo depende de uma implementação específica. Também pode ser possível que não exista um printfespecificador de formato.
Como imprimir std :: vector <> :: size_type?
Em etapas:
- Crie uma biblioteca para obter o
printfespecificador de formatação dependendo do tipo. - Molde essa biblioteca nesse tipo.
É exatamente o mesmo que as std::cout::operator<<sobrecargas estão fazendo com a impressão. Somente:
#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));
}
Um humilde hack prático
Parece não haver uma maneira simples e elegante de fazer isso, como sugerem outras respostas. O que fazer então? Por falta de uma abordagem melhor, sejamos humildes e voltemos ao básico:
- Encontre especificadores de formato printf para os maiores tipos de inteiros assinados e não assinados (em termos de tamanho) que você puder.
- Em tempo de compilação, determine a sinalização do vetor
size_typeusandostd::is_signed_t<T>. - Em tempo de execução, verifique se o valor do tamanho é pequeno o suficiente para caber no tipo de destino, caso contrário, apenas declare a falha.
- Converta o
size_typepara o tipo inteiro apropriado. - Agora você pode usar o valor de conversão em uma chamada printf.
PS - Para escolher entre os especificadores de formato assinado / não assinado, você precisará construir a string de formato dinamicamente ou escolher entre duas strings de formato ou usar compilação condicional etc. para isso - ao preço de falhar para os tamanhos maiores que precisam desse último pedaço.