-
Notifications
You must be signed in to change notification settings - Fork 67
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
rvalue variant with lvalue references does not compile #73
Comments
It appears that the issue manifests within boost::detail::variant::invoke_visitor. Here's the prototype
The second template parameter is MoveSemantics.
To be precise, if MoveSemantics == true, we always call
which casts operand, which is an int& to int&&. We can confirm this by looking at the compiler error messages from your example:
Note the "with T = int&". This tells us that the non-const lvalue ref qualifiers is properly propagated down to internal_visit. Going up the compiler trace, it would appear that depending on the ref-qualifier of the given boost::variant object, boost::detail::variant::invoke_visitor is instantiated differently. In particular, in the case where the boost::variant is an rvalue, the rvalue-ref qualified overload of apply_visitor is called
the second "true" template argument corresponds to MoveSemantics. What this means is if the boost::variant object is an rvalue, then we always attempt to move the value. In the case where the variant type is non-reference I guess that makes sense, but in the case where we have an lvalue reference (both const and non-const) in a variant, then I would argue that the variant does not own the value referred to and therefore should not attempt to move. |
As far as I can tell, the following is a legitimate code which attempts to a temporary variant to keep references. But it fails to compile:
See https://godbolt.org/z/FVVA_t for the error.
It seems
apply_visitor
is making the assumption that if a variant is rvalue, so should be the elements. But (unlike std::variant) boost::variant supports references as elements, so the two are decoupled.This makes variants impossible to use as proxy objects.
The text was updated successfully, but these errors were encountered: