将输出流上的“nullptr”格式化为十六进制地址,而不是“0”
Formatting `nullptr` on out stream as hexadecimal address, instead of `0`
我如何在输出流上格式化任何类型的空指针,最好包括立即数 nullptr
,以便打印出 0x000000000000
甚至只是 0x0
,但类似于地址值而不是无意义的 0
或 terminate 或任何非地址类的? //(nil)
或 (null)
如果不使用 printf
我也可以接受。
您可以制作一个指针格式化程序,它可以按照您喜欢的任何方式进行格式化。
例如:
#include <cstdint>
#include <iomanip>
#include <ios>
#include <iostream>
#include <sstream>
#include <string>
static auto Fmt(void const* p) -> std::string {
auto value = reinterpret_cast<std::uintptr_t>(p);
constexpr auto width = sizeof(p) * 2;
std::stringstream ss;
ss << "0x" << std::uppercase << std::setfill('0') << std::setw(width) << std::hex << value;
return ss.str();
}
int main() {
char const* p = nullptr;
std::cout << Fmt(p) << "\n";
p = "Hello";
std::cout << Fmt(p) << "\n";
}
您可以为 void 指针重载 << 运算符。
#include <iostream>
struct Foo {
void bar() {}
};
std::ostream& operator<<(std::ostream& stream, void *p) {
return stream << 0 << 'x' << std::hex << reinterpret_cast<size_t>(p) << std::dec;
}
int main() {
Foo foo;
Foo *p = &foo;
std::cout << p << std::endl;
p = nullptr;
std::cout << p << std::endl;
}
或者添加一个更灵活的包装器,因为您可以使用这两种方法,但需要输入更多内容。
#include <iostream>
struct Foo {
void bar() {}
};
struct Pointer_wrapper {
void *p_;
explicit Pointer_wrapper(void *p) :p_(p) {}
};
std::ostream& operator<<(std::ostream& stream, const Pointer_wrapper& w) {
return stream << 0 << 'x' << std::hex << reinterpret_cast<size_t>(w.p_) << std::dec;
}
using pw = Pointer_wrapper;
int main() {
Foo foo;
Foo *p = &foo;
std::cout << pw(p) << std::endl;
p = nullptr;
std::cout << pw(p) << std::endl;
}
我如何在输出流上格式化任何类型的空指针,最好包括立即数 nullptr
,以便打印出 0x000000000000
甚至只是 0x0
,但类似于地址值而不是无意义的 0
或 terminate 或任何非地址类的? //(nil)
或 (null)
如果不使用 printf
我也可以接受。
您可以制作一个指针格式化程序,它可以按照您喜欢的任何方式进行格式化。
例如:
#include <cstdint>
#include <iomanip>
#include <ios>
#include <iostream>
#include <sstream>
#include <string>
static auto Fmt(void const* p) -> std::string {
auto value = reinterpret_cast<std::uintptr_t>(p);
constexpr auto width = sizeof(p) * 2;
std::stringstream ss;
ss << "0x" << std::uppercase << std::setfill('0') << std::setw(width) << std::hex << value;
return ss.str();
}
int main() {
char const* p = nullptr;
std::cout << Fmt(p) << "\n";
p = "Hello";
std::cout << Fmt(p) << "\n";
}
您可以为 void 指针重载 << 运算符。
#include <iostream>
struct Foo {
void bar() {}
};
std::ostream& operator<<(std::ostream& stream, void *p) {
return stream << 0 << 'x' << std::hex << reinterpret_cast<size_t>(p) << std::dec;
}
int main() {
Foo foo;
Foo *p = &foo;
std::cout << p << std::endl;
p = nullptr;
std::cout << p << std::endl;
}
或者添加一个更灵活的包装器,因为您可以使用这两种方法,但需要输入更多内容。
#include <iostream>
struct Foo {
void bar() {}
};
struct Pointer_wrapper {
void *p_;
explicit Pointer_wrapper(void *p) :p_(p) {}
};
std::ostream& operator<<(std::ostream& stream, const Pointer_wrapper& w) {
return stream << 0 << 'x' << std::hex << reinterpret_cast<size_t>(w.p_) << std::dec;
}
using pw = Pointer_wrapper;
int main() {
Foo foo;
Foo *p = &foo;
std::cout << pw(p) << std::endl;
p = nullptr;
std::cout << pw(p) << std::endl;
}