There is no problem as long as you don't return a reference to a local/temporary.
Also, be sure to check the validity of the reference over time (it ends when the variant object is destructed, which is when the variant itself is destructed, or (!) when it is reinitialized).
Background and explanation
A variant contains an object of the "current" element type, and you can reference into that object perfectly fine. As long as the variant is not reinitialized to another element type (in which case the reference is "just" dangling, exactly like it would if the lifetime of the referred-to object had ended).
So if get_somet_t()
returns a T&
or T const&
(or something with a suitable implicit conversion) there is no problem.
In a simpler setting let me demonstrate valid options:
variant<int, std::string> v1 = 42;
int& i1 = get<int>(v1); // returns by ref, valid
i1 *= 2;
// now v1 contains the updated integer value 84
Likewise, you can even make variants of /just references/:
std::string s = "hello";
int answer = 42;
variant<int&, std::string&> v2(s);
get<std::string&>(v2) += " world"; // now s contains "hello world"
variant<int&, std::string&> v3(answer);
get<int&>(v3) *= 2; // now `answer` contains 84
See it all Live On Coliru
Demonstration
Put yet another way, the following is fine:
struct A { std::string a_property; };
struct B { std::string b_field; };
struct select_member : static_visitor<std::string&> {
std::string& operator()(A& a) const { return a.a_property; }
std::string& operator()(B& b) const { return b.b_field; }
};
int main()
{
variant<A,B> v = A { "some string" };
apply_visitor(select_member(), v) += " suffix";
std::cout << get<A>(v).a_property << "\n"; // prints "some string suffix"
}
See it Live On Coliru as well.