std::可选::使用 std::addressof 进行变换

R K*_*R K 5 c++ stdoptional c++23

考虑以下代码:

#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;
}
Run Code Online (Sandbox Code Playgroud)

未注释掉的行(将一个哑包装器std::addressof作为函数参数传递给std::optional::transform)可以编译并正常工作。被注释掉的行(尝试std::addressof直接使用的行)没有 - 我收到一条错误,指示模板参数推导失败(此处使用 GCC 13.2 的实时示例,尽管在 Clang 16.0 中观察到类似的行为)。为什么是这样?std::addressof标准和我周围的愚蠢包装有什么区别?

Jar*_*d42 7

std::addressof有过载...

一种用于左值 (C++11 起),另一种用于右值 (C++17 起),因此std::addressof<int>是不明确的。(即使删除重载会令人惊讶;-))。

无论如何,std::addressof不​​是一个可寻址的函数