При просмотре некоторого кода я наткнулся на конструкцию со следующей строкой:
if (const auto& foo = std::get_if<MyType>(&bar)) // note the ampersand!
, где bar
- это std::variant<MyType, OtherType>
. Проблема в том, что get_if
может возвращать нулевой указатель , и я не понимаю, почему оператор работает.
Рассмотрим этот аналог 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
?