常量自动引用绑定到(空)指针 - 实际类型是什么?
const auto reference binding to (null) pointer - what is the actual type?
在查看一些代码时,我遇到了一个包含以下行的结构:
if (const auto& foo = std::get_if<MyType>(&bar)) // note the ampersand!
其中 bar
是 std::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
的类型是什么?
请注意,对于 const auto& foo
,const
在 auto
部分是限定的,即指针而不是指针。那么 foo
的类型将是 Foo* const &
,这是对 const
的 引用(指向非 const
Foo
),但不是 const Foo* &
,这是对非 const
的 引用(指向 const
Foo
的指针)。
而 lvalue-reference 到 const
可以绑定到 f()
返回的右值,所以 const auto& foo = f();
工作正常; const Foo*& bar = f();
不会工作,因为 bar
是 lvalue-reference 到非 const
;不能绑定到右值。将 bar
的类型更改为 const Foo * const &
或 Foo* const &
(与 foo
相同)将使它起作用。
在查看一些代码时,我遇到了一个包含以下行的结构:
if (const auto& foo = std::get_if<MyType>(&bar)) // note the ampersand!
其中 bar
是 std::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
的类型是什么?
请注意,对于 const auto& foo
,const
在 auto
部分是限定的,即指针而不是指针。那么 foo
的类型将是 Foo* const &
,这是对 const
的 引用(指向非 const
Foo
),但不是 const Foo* &
,这是对非 const
的 引用(指向 const
Foo
的指针)。
而 lvalue-reference 到 const
可以绑定到 f()
返回的右值,所以 const auto& foo = f();
工作正常; const Foo*& bar = f();
不会工作,因为 bar
是 lvalue-reference 到非 const
;不能绑定到右值。将 bar
的类型更改为 const Foo * const &
或 Foo* const &
(与 foo
相同)将使它起作用。