1 // { dg-do run } 2 // { dg-options -std=c++17 } 3 4 #define assert(X) do { if (!(X)) __builtin_abort(); } while (0) 5 6 namespace std { 7 template<typename T> struct tuple_size; 8 template<int, typename> struct tuple_element; 9 } 10 11 struct A { 12 int i; getA13 template <int I> int& get() { return i; } 14 }; 15 16 template<> struct std::tuple_size<A> { static const int value = 2; }; 17 template<int I> struct std::tuple_element<I,A> { using type = int; }; 18 19 struct B { 20 int i; 21 }; 22 template <int I> int& get(B&& b) { return b.i; } 23 template <int I> int& get(B& b) { return b.i; } 24 25 template<> struct std::tuple_size<B> { static const int value = 2; }; 26 template<int I> struct std::tuple_element<I,B> { using type = int; }; 27 28 int main() 29 { 30 { 31 A a = { 42 }; 32 auto& [ x, y ] = a; 33 assert (&x == &y && &x == &a.i && x == 42); 34 35 auto [ x2, y2 ] = a; 36 assert (&x2 == &y2 && &x2 != &a.i && x2 == 42); 37 } 38 39 { 40 B b = { 42 }; 41 auto& [ x, y ] = b; 42 assert (&x == &y && &x == &b.i && x == 42); 43 44 auto [ x2, y2 ] = b; 45 assert (&x2 == &y2 && &x2 != &b.i && x2 == 42); 46 } 47 } 48