std::optional::transform 与 std::addressof

std::optional::transform with std::addressof

提问人:R K 提问时间:8/24/2023 最后编辑:DailyLearnerR K 更新时间:10/29/2023 访问量:121

问:

请考虑以下代码:

#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;
}

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

C++ C++23 标准可选

评论

0赞 Jarod42 8/24/2023
std::addressof 有重载...
1赞 R K 8/24/2023
不过,是这样吗?该链接显示在C++17之前有一个版本,在C++17之前有一个版本。自 C++17 以来也有一个显式删除的重载 - 但我不清楚为什么这应该有所作为。我已经显式复制了C++17和版本作为我的函数签名
0赞 Jarod42 8/24/2023
如果添加 ,则会添加类似的问题。template <typename T> constexpr T * arg_to_pointer(T&&) noexcept /*=delete*/;
1赞 R K 8/24/2023
确实你这样做了 - 只是我自己尝试过。所以我想我现在的问题是:为什么?为什么显式删除重载会使某些内容更加模棱两可?当然,我告诉你它不可能那么超载,从而让它变得不那么模棱两可了?
1赞 Jarod42 8/24/2023
过载解决与此类过载的定义“无关”。

答:

7赞 Jarod42 8/24/2023 #1

std::addressof 有重载...

一个用于左值(从 C++11 开始),一个用于右值(从 C++17 开始),所以是模棱两可的。(即使采取删除的重载会令人惊讶;-))。std::addressof<int>

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

评论

1赞 R K 8/24/2023
尚未实现可寻址函数约束。谢谢你