Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any practical reason why std::get_if (std::variant) takes a variant argument by pointer instead of by value/&/const&?

I've never used std::get_if, and since its name is different from std::get, I don't see a reason why its argument should be a pointer¹ (whereas std::get has a by-reference parameter).


¹If it was named std::get too, then overload resolution would be a reason enough.


Yes, my question could be duped to the question Is it absolutely necessary for std::any_cast() and std::get_if(std::variant) to take pointer as an argument?, but the point is that there's no answer there that addresses std::get_if vs std::get, just one comment; the only answer concentrates on std::any_cast.

like image 467
Enlico Avatar asked Sep 21 '21 14:09

Enlico


2 Answers

This is because get_if is noexcept, so an exception will never be thrown. In order to achieve this, it must return a pointer so that nullptr can be returned when the access fails.

Because it returned the pointer, it must take the pointer of the variant. If it takes the reference of variant, then it must be able to accept the type of variant&, const variant&, variant&& and const variant&&, but it does not make sense for the pointer to remain ref-qualified.

Considering that get_if accepts variant&&, what you do is return the address of an xvalue, which is terrible. Even if get_if only allows variant& and const variant&, the latter can still accept a variant&& and return a dangling.

like image 61
康桓瑋 Avatar answered Oct 16 '22 17:10

康桓瑋


From what I can tell, it is based off dynamic cast logic. The dynamic cast that can fail takes a pointer and returns a pointer.

Similarly, get that can fail takes a pointer and returns one.

But really it looks like a tiny bikeshed decision of not much importance.

like image 44
Yakk - Adam Nevraumont Avatar answered Oct 16 '22 15:10

Yakk - Adam Nevraumont