Search code examples
c++c++17pass-by-referencestd-variantpass-by-pointer

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.


Solution

  • 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.