【问题标题】:const auto reference binding to (null) pointer - what is the actual type?const 自动引用绑定到(空)指针 - 实际类型是什么?
【发布时间】:2019-05-09 09:03:34
【问题描述】:

在查看一些代码时,我遇到了一个包含以下行的构造:

if (const auto& foo = std::get_if<MyType>(&bar)) // note the ampersand!

其中barstd::variant&lt;MyType, OtherType&gt;。这里的问题是 get_if may return a null pointer 我不明白为什么该语句有效。

考虑这个类似的 MCVE:

#include <iostream>

struct Foo { int a = 42; };

Foo* f() { return nullptr; }

int main() {
    const auto& foo = f();          // Returns a nullptr that binds to Foo*& - UB?
    //static_assert(std::is_same<decltype(foo), const Foo*&>::value); // -> Fails
    //const Foo*& bar = f(); // -> Fails

    if (foo)    std::cout << foo->a << std::endl;
    else        std::cout << "nullpointer" << std::endl;
}

main() 的第一行工作正常,我希望bar 的类型为const Foo*&amp;,但静态断言失败。不出所料,以下行也无法使用 cannot bind non-const lvalue reference of type 'const Foo*&amp;' to an rvalue of type 'const Foo*' 编译。

main 的第一条语句发生了什么?这是 UB 还是该标准是否包含一些允许其合法的隐藏秘密? bar的类型是什么?

【问题讨论】:

  • 指针值的可能空值无关紧要 - 指向 T 的空指针与指向 T 的所有其他指针具有相同的类型。 nullptr 不是指针,而是可以隐式转换为任何类型的空指针的对象。它的类型是nullptr_t
  • get_if 不能返回 nullptr(这是一个类类型的值 nullptr_t)。它必须返回一个指针值,它可以是一个空指针。
  • 感谢@M.M. 的留言。然后我假设该引用具有误导性,因为它明确说明了返回值:“指向存储在指向变量中的值的指针或 null 指针 错误。” ?无论如何,我似乎需要更新我对空指针的了解。
  • @andreee “空指针”是指针的可能值。 nullptr 不是空指针(也不是指针);它是一个可以隐式转换为任何类型的空指针的表达式。
  • @M.M 我想我已经搞定了......我想我在路上搞混了几件事,但我想现在我就在那里。我已经阅读了标准和参考中的一些部分,现在对我来说似乎很清楚。非常感谢您的评论,我从来没有想过我一直对空指针有一个完全错误的想法!

标签: c++ pointers reference c++17 auto


【解决方案1】:

请注意,对于const auto&amp; fooconstauto 部分上是合格的,即指针而不是指针。那么foo 的类型将是Foo* const &amp;,这是对const引用(指向非constFoo 的指针),但不是const Foo* &amp;,这是一个对非const的引用(指向constFoo的指针)。

const 的左值引用可以绑定到f() 返回的右值,所以const auto&amp; foo = f(); 可以正常工作; const Foo*&amp; bar = f(); 不起作用,因为bar 是对非const 的左值引用;不能绑定到右值。将bar 的类型更改为const Foo * const &amp;Foo* const &amp;(与foo 相同)将使其工作。

【讨论】:

  • 在处理 variable-pointer-to-const vs const-pointer-to-variable 时,我发现将const 始终放在 right它是限定的(并且不使用扩展名,如果右侧没有类型,则它限定左侧的类型)。因此fooFoo* const &amp;,而不是Foo const* &amp;
  • @MartinBonner East-const 4 lyfe!
  • 感谢您的回答!您是否有任何机会参考该标准?我自己找不到它们(至少对于那种特殊情况不会)......
  • @andreee 您想要参考哪个部分?是的,在标准中找到直截了当的陈述并不容易,尤其是对于我回答的第一段..
  • @andreee 确切地说,它与nullptr 无关,something_returning_nullptr() 返回的始终是prvalue,尽管函数是否返回nullptr"函数调用或重载的运算符表达式,其返回类型为非引用,如str.substr(1, 2)str1 + str2it++;"
猜你喜欢
  • 1970-01-01
  • 2019-11-10
  • 1970-01-01
  • 2013-05-14
  • 2011-05-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多