-
-
Notifications
You must be signed in to change notification settings - Fork 264
Structured bindings with tuple shows incorrect tuple_element usage #277
Copy link
Copy link
Closed
Labels
enhancementNew feature or requestNew feature or request
Description
This example:
#include <tuple>
int f(std::tuple<int, double> x) {
auto [i, j] = x;
return i;
}expands as:
#include <tuple>
int f(std::tuple<int, double> x)
{
std::tuple<int, double> __x4 = std::tuple<int, double>(x);
std::tuple_element<0, std::tuple<int, double> >::type& i = std::get<0UL>(__x4);
std::tuple_element<0, std::tuple<double> >::type& j = std::get<1UL>(__x4);
return i;
}This is equivalent, but I think you really want std::tuple_element<1, std::tuple<int, double> >::type there instead (since that's what the specification says).
With a different custom structured binding implementation:
#include <tuple>
struct Point {
int data[2];
};
template <std::size_t N>
constexpr int& get(Point& p) {
return p.data[N];
}
namespace std {
template <> struct tuple_size<Point> : integral_constant<size_t, 2> { };
template <size_t N> struct tuple_element<N, Point> : tuple_element<N-1, Point> { };
template <> struct tuple_element<0, Point> { using type = int; };
}
int f(Point p) {
auto& [x, y] = p;
return x;
}the binding there shows up as:
int f(Point p)
{
Point & __p19 = p;
std::tuple_element<0, Point>::type& x = get<0UL>(__p19);
std::tuple_element<0, Point>::type& y = get<1UL>(__p19);
return x;
}Instead of std::tuple_element<1, Point>::type.
Which gets even more confusing if I wrote it this way:
#include <tuple>
struct Point {
int data[2];
};
template <std::size_t N>
constexpr int& get(Point& p) {
return p.data[N];
}
template <typename T> struct type_t { using type = T; };
namespace std {
template <> struct tuple_size<Point> : integral_constant<size_t, 2> { };
template <size_t N> struct tuple_element<N, Point> : type_t<int> { };
}
int f(Point p) {
auto& [x, y] = p;
return x;
}because then I get:
int f(Point p)
{
Point & __p20 = p;
type_t<int>::type& x = get<0UL>(__p20);
type_t<int>::type& y = get<1UL>(__p20);
return x;
}I think in the customization point case, prefer to keep tuple_element<N, T>::type and not go through base classes of the particular tuple_element instantiation? Or, if you do, then go all the way and rewrite the above as int& instead of going most of the way through the instantiation process.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or request