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?
std::addressof
has overloads...
One for lvalue (since C++11), and one for rvalue (since C++17), so std::addressof<int>
is ambiguous. (even if it would be surprising to take the deleted overload ;-) ).
Anyway, std::addressof
is not a addressable function.