const自动引用绑定到(null)指针-实际类型是什么?

时间:2019-05-09 09:03:34

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

在查看一些代码时,我遇到了下面一行的结构:

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

其中barstd::variant<MyType, OtherType>。这里的问题是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*&,但是静态断言失败。不足为奇的是,以下行也无法使用cannot bind non-const lvalue reference of type 'const Foo*&' to an rvalue of type 'const Foo*'进行编译。

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

1 个答案:

答案 0 :(得分:10)

请注意,对于const auto& fooconstauto部分是合格的,即指针而不是指针。然后foo的类型将是Foo* const &,这是对const引用(指向非const Foo的指针) ,但不是const Foo* &,它是对非const (指向const Foo的指针的引用)。

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