std::addressof不能直接用&代替,因为&可能被类重载而返回假地址,而std::addressof通过底层机制强制获取对象真实内存地址,需包含头文件且仅接受左值。

std::addressof 为什么不能直接用 & 运算符代替
因为 & 运算符可能被重载,返回的不一定是对象在内存中的真实地址。比如自定义类重载了 operator&,返回的是某个代理指针或空指针,这时 &obj 就不可靠。而 std::addressof 是标准库提供的“绕过重载”的机制,它通过底层位操作(如 reinterpret_cast + const_cast)确保拿到的是对象实际的存储地址。
std::addressof 的基本用法和常见误用
必须包含头文件 <memory></memory>;传入左值(不能是右值或字面量),否则编译失败。典型错误包括:
- 对临时对象调用:
std::addressof(std::string("hello"))→ 编译错误,因为临时对象不是可取地址的左值 - 对数组名误用:
int arr[5]; std::addressof(arr)是合法的,但返回的是整个数组的地址(类型为int(*)[5]),不是首元素地址;若想取首元素地址,应写std::addressof(arr[0]) - 忽略 const 限定:
const int x = 42; auto p = std::addressof(x);返回的是const int*,不能隐式转为int*
什么时候必须用 std::addressof 而不是 &
主要出现在需要绕过重载、保证地址唯一性的底层场景中,比如:
- 实现容器或智能指针的内部地址计算(如
std::allocator::address内部就调用std::addressof) - 调试时验证对象布局,尤其当类有重载的
operator&且你怀疑它返回了假地址 - 与 C API 交互时传递真实地址(例如绑定到
mmap或硬件寄存器映射区) - 编写泛型代码时无法预知模板参数是否重载了
operator&,安全起见统一用std::addressof
std::addressof 在 C++11 之后的兼容性与性能影响
std::addressof 自 C++11 引入,所有现代标准库都支持;它的实现是 constexpr(C++17 起),可在编译期求值。性能上完全无开销——现代编译器会将其优化为纯地址取值指令,和裸 & 在未重载时生成的汇编一致。但要注意:如果对象本身位于未分配/未初始化内存(比如仅声明未构造的 std::aligned_storage 区域),调用 std::addressof 合法,但解引用该地址仍是未定义行为。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











