Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I let compiler to deduce a type of nullptr?

Tags:

c++

I am learning c++. I would like to let compiler to deduce nullptr as shared_ptr. Please read the following code,

struct A {};

struct B {
    std::shared_ptr<A> a;
};

struct Tag {
    std::shared_ptr<B> b;
};

auto GetSharedPtrClassB(Tag* tag) {
    if (tag) {
        auto& sharedB = *(tag->b);
        return sharedB.a;
    } else {
        return nullptr;  // Error : compiler cannot deduce type of nullptr.
    }
}

In GetSharedPtrClassB, nullptr cannot be deduced as std::shared_ptr<A>. The error messages are following,

error: inconsistent deduction for ‘auto’: ‘std::shared_ptr<A>’ and then ‘std::nullptr_t’

How can I let compiler deduce nullptr as std::shared_ptr<A>? I can provide a type decltype(*(tag->b)), but I cannot think of the next step to provide a type std::shared_ptr<A>.

Thank you very much.

like image 202
mora Avatar asked Dec 04 '22 22:12

mora


1 Answers

Use a conditional operator to force the conversion from nullptr to "whatever":

auto GetSharedPtrClassB(Tag* tag) {
    return tag ? tag->b->a : nullptr;
}

Conversion from one operand to the other in a conditional operator is well-defined (see [expr.cond]), here the nullptr gets converted to an object of type decltype(tag->b->a).

On the other hand, the rules for return type deduction when using auto without a trailing return type are very strict - the deduced type must be the same for each return statement ([dcl.spec.auto/9]):

If a function with a declared return type that contains a placeholder type has multiple return statements, the return type is deduced for each return statement. If the type deduced is not the same in each deduction, the program is ill-formed.


If your function cannot be reduced to a conditional operator, you can use a trailing return type:

auto GetSharedPtrClassB(Tag* tag) -> decltype(tag->b->a) {
    if (tag) {
        auto& sharedB = *(tag->b);
        return sharedB.a;
    } else {
        return {};
    }
}
like image 105
Holt Avatar answered Feb 22 '23 10:02

Holt