¿Cómo imprimir std::vector<>::size_type?
std::vectortiene un tipo de miembro size_type. ¿Cuál es su especificador de formato printf?
Tenga en cuenta que size_typeno es 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
Respuestas
¿Cuál es su especificador de formato printf?
Nadie sabe. No se especifica qué std::vector<?>::size_typees exactamente, excepto que es un "tipo entero sin signo" int Biblioteca de contenedores de C++, Requisitos generales de contenedores . Debido printfa que el especificador de formato depende del tipo, todo depende de la implementación particular. También puede ser posible que no exista un printfespecificador de formato.
¿Cómo imprimir std::vector<>::size_type?
En pasos:
- Cree una biblioteca para obtener
printfel especificador de formato según el tipo. - Plantilla esa biblioteca en ese tipo.
De todos modos, es lo mismo que std::cout::operator<<hacen las sobrecargas para imprimir. Sólo:
#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));
}
Un humilde truco práctico
Parece que no hay una forma elegante y directa de hacer esto, como sugieren otras respuestas. ¿Qué hacer, entonces? A falta de un mejor enfoque, seamos humildes y volvamos a lo básico:
- Encuentre especificadores de formato printf para los tipos enteros con y sin signo más grandes (en cuanto al tamaño) que pueda.
- En tiempo de compilación, determine la firma del vector
size_typeusandostd::is_signed_t<T>. - En tiempo de ejecución, verifique que el valor del tamaño sea lo suficientemente pequeño como para caber en el tipo de destino; de lo contrario, simplemente declare la falla.
- Convierta el
size_typetipo entero apropiado. - Ahora puede usar el valor de conversión en una llamada de printf.
PD: para elegir entre los especificadores de formato firmado/sin firmar, deberá construir la cadena de formato dinámicamente, o elegir entre dos cadenas de formato, o usar la compilación condicional, etc. En su lugar, puede optar por el tipo firmado más grande y emitir siempre en eso , al precio de fallar en los tamaños más grandes que necesitan ese último bit.