Soonts
Soonts

Reputation: 21936

How to get a reference to variant’s value?

I have std::variant where all classes are derived from the same base. I want to cast variant to base.

return std::visit( []( const Base& b ) { return b; }, v );

This compiles but gives warning C4172: returning address of local variable or temporary

Is there a way to visit std::variant in place, without making local or temporary copies?

Or if it’s impossible, how can I cast the value to void* so I can use static_cast ?

Update: I thought the example should be obvious, but it's not, here's the complete repro:

#include <variant>

struct Base {};
struct A : Base {};
struct B : Base {};

const Base& cast( const std::variant<A, B>& v )
{
    return std::visit( []( Base const& b ) { return b; }, v );
}

int main()
{
    std::variant<A, B> v{ A{} };
    const auto& b = cast( v );
}

Upvotes: 3

Views: 2572

Answers (1)

Justin
Justin

Reputation: 25297

Lambdas have return type deduction, but they deduce the return type by value. It's as if they are a function returning auto, not decltype(auto). If you want to return by reference, you need to specify the return type.

Thus, [](const Base& b) { return b; } returns by value, copying b. Explicitly specify the return type to force it to return by reference:

const Base& cast( const std::variant<A, B>& v )
{
    return std::visit( []( Base const& b ) -> Base const& { return b; }, v );
}

Upvotes: 5

Related Questions