首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何让编译器推断出一种nullptr类型?

如何让编译器推断出一种nullptr类型?
EN

Stack Overflow用户
提问于 2017-06-12 14:15:17
回答 4查看 863关注 0票数 4

我正在学习c++。我希望让编译器将nullptr推断为shared_ptr。请阅读以下代码,

代码语言:javascript
复制
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.
    }
}

GetSharedPtrClassB中,nullptr不能被推断为std::shared_ptr<A>。错误消息如下,

代码语言:javascript
复制
error: inconsistent deduction for ‘auto’: ‘std::shared_ptr<A>’ and then ‘std::nullptr_t’

如何让编译器将nullptr推断为std::shared_ptr<A>?我可以提供一个类型的decltype(*(tag->b)),但我想不出下一步提供std::shared_ptr<A>类型的步骤。

非常感谢。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2017-06-12 14:21:00

使用条件运算符强制将nullptr转换为“任何”:

代码语言:javascript
复制
auto GetSharedPtrClassB(Tag* tag) {
    return tag ? tag->b->a : nullptr;
}

在条件运算符中,从一个操作数转换到另一个操作数是非常明确的(参见expr.cond),在这里,nullptr被转换为decltype(tag->b->a)类型的对象。

另一方面,在使用没有尾随返回类型的auto时,返回类型的演绎规则非常严格--对于每个return语句(dcl.spec.Auto/9),推导的类型必须是相同的:

如果包含占位符类型的声明返回类型的函数有多个返回语句,则为每个返回语句推导返回类型。如果推导的类型在每个演绎中不相同,则程序是错误的。

如果不能将函数简化为条件运算符,则可以使用尾随返回类型:

代码语言:javascript
复制
auto GetSharedPtrClassB(Tag* tag) -> decltype(tag->b->a) {
    if (tag) {
        auto& sharedB = *(tag->b);
        return sharedB.a;
    } else {
        return {};
    }
}
票数 9
EN

Stack Overflow用户

发布于 2017-06-12 14:18:22

您可以返回默认构造的shared_ptr。

代码语言:javascript
复制
auto GetSharedPtrClassB(Tag* tag) {
    if (tag) {
        auto& sharedB = *(tag->b);
        return sharedB.a;
    } else {
        return std::shared_ptr<A>{};
    }
}
票数 4
EN

Stack Overflow用户

发布于 2017-06-12 14:26:08

我假设您的代码实际上是在泛型上下文中使用的。如果您的代码不使用模板不使用解密类型,请直接指定类型。

若要推断返回类型,所有返回语句都必须计算为相同类型的表达式。在您的代码中,有两个具有两种不同类型的返回语句。一个用std::shared_ptr<A>,一个用std::nullptr_t

有两种解决方案:在两个返回语句中使用相同的类型,或者显式定义返回类型。

下面是如何返回相同类型的内容:

代码语言:javascript
复制
auto GetSharedPtrClassB(Tag* tag) {
    if (tag) {
        auto& sharedB = *(tag->b);
        return sharedB.a;
    }

    // empty constructor same as initializing with `nullptr`
    return decltype(tag->b->a){};
}

或显式定义返回类型:

代码语言:javascript
复制
auto GetSharedPtrClassB(Tag* tag) -> decltype(tag->b->a) {
    if (tag) {
        auto& sharedB = *(tag->b);
        return sharedB.a;
    }

    // empty constructor same as initializing with `nullptr`
    return {};
}

顺便说一句,在您的代码中,auto& sharedB = *(tag->b); return sharedB.a;可以简化为return tag->b->a;

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44501629

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档