1 // { dg-additional-options -std=c++17 } 2 // { dg-do compile } 3 4 #include <memory> 5 #include <tuple> 6 #include <string> 7 8 struct X : private std::shared_ptr<int> 9 { 10 std::string fun_payload; 11 }; 12 get(X & x)13template<int N> std::string& get(X& x) 14 { 15 if constexpr(N==0) return x.fun_payload; 16 } 17 18 namespace std { 19 template<> class tuple_size<X> : public std::integral_constant<int, 1> {}; 20 template<> class tuple_element<0, X> {public: using type = std::string;}; 21 } 22 23 struct X2 : private std::shared_ptr<int> 24 { 25 int fun_payload; 26 template <class T> void get(); 27 }; 28 get(X2 & x)29template<int N> int& get(X2& x) 30 { 31 if constexpr(N==0) return x.fun_payload; 32 } 33 34 namespace std { 35 template<> class tuple_size<X2> : public std::integral_constant<int, 1> {}; 36 template<> class tuple_element<0, X2> {public: using type = int;}; 37 } 38 39 class X3 40 { 41 double fun_payload; 42 public: get()43 template <int N> double& get() 44 { 45 if constexpr(N==0) return fun_payload; 46 } 47 }; 48 49 namespace std { 50 template<> class tuple_size<X3> : public std::integral_constant<int, 1> {}; 51 template<> class tuple_element<0, X3> {public: using type = double;}; 52 } 53 main()54int main() 55 { 56 X x; 57 auto& [b1] = x; 58 X2 x2; 59 auto& [b2] = x2; 60 X3 x3; 61 auto& [b3] = x3; 62 } 63