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

Consider the following code:

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

The line that is not commented out (that passes a dumb wrapper around std::addressof as the function parameter to std::optional::transform) compiles and works just fine. The line that is commented out (the one that tries to use std::addressof directly) does not – I get an error indicating that template argument deduction failed (live example here using GCC 13.2, though similar behavior is observed with Clang 16.0). Why is this? What is the difference between the standard std::addressof and my dumb wrapper around it?

>Solution :

std::addressof has overloads…

One for lvalue (since C++11), and one for rvalue (since C++17), so std::addressof<int> is ambiguous. (even it would be surprising to take the deleted overload 😉 ).

Anyway, std::addressof is not a addressable function.

Leave a Reply