Dmitry
Dmitry

Reputation: 1319

Return reference and value inside std::tuple

Is it possible to return somehow reference and value inside std::tuple.

Consider something like this:

#include <tuple>
#include <assert.h>

struct A
{
    A() = default;
    A(const A&) = delete;
    A& operator=(const A&) = delete;
    int test = 99;
};

A a;

A& get_A() {return a;}

auto return_tuple_with_reference_and_value()
{
    return std::forward_as_tuple(get_A(), 20);
}

int main()
{
    auto[reference_to_a, value] = return_tuple_with_reference_and_value();
    assert(reference_to_a.test == 99);
    assert(value == 20);
    reference_to_a.test = 1111;
    assert(a.test == 1111);
}

Can we make it work? Right now it has UB (dangling reference to '20').

Upvotes: 1

Views: 1359

Answers (2)

Caleth
Caleth

Reputation: 62874

You can use std::make_tuple and pass a reference_wrapper

For each Ti in Types..., the corresponding type Vi in VTypes... is std::decay<Ti>::type unless application of std::decay results in std::reference_wrapper<X> for some type X, in which case the deduced type is X&.

auto return_tuple_with_reference_and_value()
{
    return std::make_tuple(std::ref(get_A()), 20);
}

Upvotes: 2

HolyBlackCat
HolyBlackCat

Reputation: 96336

I can't find a standard function that does that, but writing one is not hard:

template <typename ...P>
auto foo(P &&... params)
{
    return std::tuple<P...>(std::forward<P>(params)...);
}

Upvotes: 1

Related Questions