我怎样才能让编译器推导出一种类型的 nullptr
How can I let compiler to deduce a type of nullptr?
我正在学习c++。我想让编译器推断 nullptr 为shared_ptr。请阅读以下代码,
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>
。错误消息如下,
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>
。
谢谢。
使用条件运算符强制从nullptr
转换为"whatever":
auto GetSharedPtrClassB(Tag* tag) {
return tag ? tag->b->a : nullptr;
}
在条件运算符中从一个操作数到另一个操作数的转换是明确定义的(请参阅 [expr.cond](,此处nullptr
转换为类型为 decltype(tag->b->a)
的对象。
另一方面,使用没有尾随返回类型的auto
时返回类型推断的规则非常严格 - 每个return
语句的推导类型必须相同 ([dcl.spec.auto/9](:
如果具有包含占位符类型的声明返回类型的函数具有多个 return 语句, 为每个 return 语句推导返回类型。如果每次扣除的类型不同, 程序格式不正确。
如果函数不能简化为条件运算符,则可以使用尾随返回类型:
auto GetSharedPtrClassB(Tag* tag) -> decltype(tag->b->a) {
if (tag) {
auto& sharedB = *(tag->b);
return sharedB.a;
} else {
return {};
}
}
改为返回默认构造shared_ptr。
auto GetSharedPtrClassB(Tag* tag) {
if (tag) {
auto& sharedB = *(tag->b);
return sharedB.a;
} else {
return std::shared_ptr<A>{};
}
}
我将假设您的代码实际上是在通用上下文中使用的。如果您的代码不使用模板,则不使用 decltype,请直接指定类型。
若要推断返回类型,所有 return 语句的计算结果必须为相同类型的表达式。在您的代码中,您有两个具有两种不同类型的 return 语句。一个有std::shared_ptr<A>
,一个有std::nullptr_t
。
有两种解决方案:在两个 return 语句中使用相同的类型,或显式定义返回类型。
下面介绍如何返回相同的类型:
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){};
}
或者显式定义返回类型:
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;
像这样使用static_cast
:
auto GetSharedPtrClassB(Tag* tag) {
if (tag) {
auto& sharedB = *(tag->b);
return sharedB.a;
} else {
return static_cast<std::shared_ptr<A> >(nullptr);
}
}
- 有符号的int和int-有没有一种方法可以在C++中区分它们
- 有一个打印语句的函数是一种糟糕的编程实践吗
- 有没有一种方法可以创建一个带有哈希表的数据库,该哈希表具有恒定时间查找功能
- 有没有一种方法可以在编译时获得作用域类名
- 对于C++中使用智能指针的指针算术限制,有没有一种变通方法
- 一种在C++中读取TXT配置文件的简单方法
- 有没有一种方法可以测量c++程序的运行时内存使用情况
- 有没有一种方法可以使用placement new将堆叠对象分配给分配的内存
- 在调用接收数组的方法时,模板化数组大小是不是一种糟糕的做法
- 有没有一种方法可以通过"typedef"为重新定义的基本类型定义特征和强制转换运算符
- 有没有一种"cleaner"的方法可以在指向基的指针向量中找到派生类的第一个实例?
- 有没有一种代码密度较低的方法来使用非默认构造函数初始化数组?
- 将错误返回给调用方而不是立即在 C++ 中抛出错误是否是一种好的做法
- 在 c++ 中,有一种方法可以创建一个包含地图作为值的树状地图?
- 有没有一种优雅而快速的方法来测试整数中的 1 位是否位于连续区域
- 在运行时检查继承是否只有一种类型和 void*
- C++ STD 函数运算符:有没有一种方法可以通过函数将一个向量映射到另一个向量上?
- 找到一种有效的方法,在 2 个巨大的缓冲区上执行 MAX,每字节字节
- 我怎样才能让编译器推导出一种类型的 nullptr
- "delete p; p = NULL(nullptr);"是一种反模式吗?