1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
|
#include <cmath>
#include <iostream>
#include <string>
#include <tuple>
//+1
class Euclid
{
size_t d_x;
size_t d_y;
public:
Euclid(size_t x = 0, size_t y = 0);
double distance() const; // sqrt(d_x * d_x + d_y * d_y)
};
//+1
Euclid::Euclid(size_t x, size_t y)
:
d_x(x),
d_y(y)
{}
double Euclid::distance() const
{
return sqrt(d_x * d_x + d_y * d_y);
}
//+1
class Data
{
std::string d_text{ "hello from Data" };
Euclid d_euclid;
public:
void setXY(size_t x, size_t y);
Euclid factory() const;
double distance() const;
std::string const &text() const;
//+1
//+2
template <size_t Nr>
auto get() const
{
if constexpr (Nr == 0)
return factory();
if constexpr (Nr == 1)
return distance();
if constexpr (Nr == 2)
return text();
static_assert(Nr >= 0 and Nr < 3);
}
//+2
//+1
};
//+1
void Data::setXY(size_t x, size_t y)
{
d_euclid = Euclid{ x, y };
}
Euclid Data::factory() const
{
return d_euclid;
}
double Data::distance() const
{
return d_euclid.distance();
}
std::string const &Data::text() const
{
return d_text;
}
//+3
template<>
struct std::tuple_size<Data>
{
static size_t const value = 3;
};
//+3
//+4
template<size_t Nr>
struct std::tuple_element<Nr, Data>
{
using type = decltype( declval<Data>().get<Nr>() );
// if get<Nr> is a free function use:
// decltype( get<Nr>( declval<Data>() ) );
};
//+4
using namespace std;
//+5
int main()
{
Data data;
auto &[ ef, dist, txt ] = data;
// or maybe:
// auto &&[ ef, dist, txt ] = Data{};
cout << dist << ' ' << txt << '\n';
Data array[5];
for (auto &[ ef, dist, txt]: array)
cout << "for: " << dist << ' ' << txt << '\n';
}
//+5
|