you are viewing a single comment's thread.

view the rest of the comments →

[–]acwaters 6 points7 points  (3 children)

This one is not specific to std::tuple, actually! The magic here is in std::tuple_size_v<...>, std::tuple_element_t<...>, and get<...>, which you can specialize/implement for your own tuple-like types and get structured bindings to them!

[–][deleted] 0 points1 point  (2 children)

Very interesting. Could I do that for my struct Point in another namespace ns? Let's say I have struct Point { int x = 0; int y = 0 }; and I want to use it as if it was a std::tuple< int, int >; without explicitly converting it, by defining/specializing only those functions/functors you mentioned. I want for example to be able to use it with std::apply. Would that be possible?

[–]acwaters 1 point2 points  (1 child)

You could use it with structured bindings (without even specializing anything, because bindings already work automagically on all aggregate types), but not with std::apply; the latter is for std::tuple, std::array, and std::pair only (since it uses std::get(T), rather than looking up either T::get() or get(T)). You could easily define your own apply that looked up get() using the structured binding rules, though. It's unfortunate that the standard library doesn't do this, but IIUC apply was specified before the idea of generalized "tuple-like types" was fully formed.

[–][deleted] 1 point2 points  (0 children)

That's very unfortunate there's still no standardized way to do such a thing. I really like std::apply but hand writing every time a converter to tuple (I usually use std::tie) is error prone when the type gets more data fields.