Providing type-bound root access for a class

I am trying to support tuple-like structured binding access for a class. For simplicity, I will use the following class in the rest of this post:

struct Test
{
    int v = 42;
};

(I know this class supports structured bindings out of the box, but let it not.)

To enable tuple-like member accessTest , we must specialize in std::tuple_sizeand std::tuple_element:

namespace std
{

template<>
struct tuple_size<Test>
{
    static const std::size_t value = 1;
};

template<std::size_t I>
struct tuple_element<I, Test>
{
    using type = int;
};

}

And we need the last part, either Test::get<i>, or a function get<i>(Test)in the namespace Test. Let the latter be realized:

template<std::size_t I>
int get(Test t)
{
    return t.v;
}

It works. However, I would like to return a link to a member Test, for example, like std::get(std::tuple). Therefore, I implement getas follows:

template<std::size_t I>
int& get(Test& t)
{
    return t.v;
}

template<std::size_t I>
const int& get(const Test& t)
{
    return t.v;
}

, ,

auto test = Test{};
auto [v] = test;

(GCC 7.1):

'std:: tuple_element < 0, Test > :: type & {aka int &} 'const int

, , get<i>(const Test&). a const int&, v const int, .

this, auto [v] = test;

auto e = test;
std::tuple_element<0, Test>::type& v = get<0>(e)

, get<i>(Test&).

, get ?

+6
1

, auto [v] , test test get x.

, get rvalue:

template<std::size_t I>
int&& get(Test&& t)
{
    return std::move(t.v);
}
+6

All Articles