c++pointersnullptrdecltype-auto

inconsistent deduction with decltype(auto) when returning pointer or nullptr


When using decltype(auto) as return type of a template function that is supposed to return a pointer, I've got an issue when this function can return a valid address or nullptr.
Here is an example:

struct S {
    bool condition;
    int data;
    template <typename Self>
    static decltype(auto) GetByAddress(Self* self) {
        if (self->condition) {
            return &self->data;
        }
        return nullptr;
    }
    int* GetByAddress() { return GetByAddress(this); }
    int const* GetByAddress() const { return GetByAddress(this); }
};

LIVE
Nb maybe that deducing this can be used in C++23 for this specific example but I'm looking for a fix in C++17 or 20.

I may use std::optional or some equivalent wrapper of the return type but what I really want to know is how to use automatic type deduction for pointer where nullptr is a possible outcome.

In this oversimplified example, this is a solution:

 static decltype(auto) GetByAddress(Self* self) {
     using ptr = decltype(&self->data);
     if (self->condition) {
         return &self->data;
     }
     return ptr{nullptr};
 }

LIVE
but it feels like it cannot be easily applied in more complex situation.


Solution

  • Not only is std::nullptr_t a distinct type, it is not even a pointer type, and the return type inference will not try to convert one expression to the other type.

    A conditional expression will do that, however:

        return self->condition ? &self->data : nullptr;
    

    should work.

    In more complex situations, you're left with the explicit conversion.