考虑以下代码:
#include <memory>
#include <optional>
template <typename T>
constexpr T * arg_to_pointer(T & arg) noexcept {
return std::addressof(arg);
}
int main() {
std::optional<int> foo;
auto * test = foo.transform(arg_to_pointer<int>).value_or(nullptr);
//auto * test = foo.transform(std::addressof<int>).value_or(nullptr);
return 0;
}
未注释掉的行(将一个哑包装器std::addressof
作为函数参数传递给std::optional::transform
)可以编译并正常工作。被注释掉的行(尝试std::addressof
直接使用的行)没有 - 我收到一条错误,指示模板参数推导失败(此处使用 GCC 13.2 的实时示例,尽管在 Clang 16.0 中观察到类似的行为)。为什么是这样?std::addressof
标准和我周围的愚蠢包装有什么区别?
std::addressof
有过载...一种用于左值 (C++11 起),另一种用于右值 (C++17 起),因此
std::addressof<int>
是不明确的。(即使删除了重载也会令人惊讶;-))。无论如何,
std::addressof
不是一个可寻址的函数。