Considere o seguinte código:
#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;
}
A linha que não está comentada (que passa um wrapper idiota std::addressof
como parâmetro de função para std::optional::transform
) compila e funciona perfeitamente. A linha comentada (aquela que tenta usar std::addressof
diretamente) não - recebo um erro indicando que a dedução do argumento do modelo falhou (exemplo ao vivo aqui usando o GCC 13.2, embora um comportamento semelhante seja observado com o Clang 16.0). Por que é isso? Qual é a diferença entre o padrão std::addressof
e meu invólucro idiota?
std::addressof
tem sobrecargas...Um para lvalue (desde C++ 11) e outro para rvalue (desde C++ 17), portanto
std::addressof<int>
é ambíguo. (até mesmo seria surpreendente aceitar a sobrecarga excluída ;-)).De qualquer forma,
std::addressof
não é uma função endereçável .