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.
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 {};
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With