#include <iostream>
#include <limits>
#include <type_traits>
using namespace std;
struct vec
{
double x;
double y;
double z;
};
namespace details
{
template <typename T>
using subscript_function = double(*)(const T&);
template <typename T>
constexpr double X(const T& param) { return param.x; }
template <typename T>
constexpr double Y(const T& param) { return param.y; }
template <typename T>
constexpr double Z(const T& param) { return param.z; }
}
template <typename T, typename = void>
constexpr details::subscript_function<T> my_temp[] = { &details::X<T>, &details::Y<T> };
template <typename T>
constexpr details::subscript_function<T> my_temp<T, enable_if_t<is_floating_point<decltype(details::X(T()))>::value, T>>[] = { &details::X<T>, &details::Y<T>, &details::Z<T> };
int main() {
vec foo = { 1.0, 2.0, 3.0 };
for(const auto i : my_temp<decltype(foo)>) {
cout << (*i)(foo) << endl;
}
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8bGltaXRzPgojaW5jbHVkZSA8dHlwZV90cmFpdHM+Cgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKc3RydWN0IHZlYwp7CiAgZG91YmxlIHg7CiAgZG91YmxlIHk7CiAgZG91YmxlIHo7Cn07CgpuYW1lc3BhY2UgZGV0YWlscwp7CiAgdGVtcGxhdGUgPHR5cGVuYW1lIFQ+CiAgdXNpbmcgc3Vic2NyaXB0X2Z1bmN0aW9uID0gZG91YmxlKCopKGNvbnN0IFQmKTsKCiAgdGVtcGxhdGUgPHR5cGVuYW1lIFQ+CiAgY29uc3RleHByIGRvdWJsZSBYKGNvbnN0IFQmIHBhcmFtKSB7IHJldHVybiBwYXJhbS54OyB9CgogIHRlbXBsYXRlIDx0eXBlbmFtZSBUPgogIGNvbnN0ZXhwciBkb3VibGUgWShjb25zdCBUJiBwYXJhbSkgeyByZXR1cm4gcGFyYW0ueTsgfQoKICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4KICBjb25zdGV4cHIgZG91YmxlIFooY29uc3QgVCYgcGFyYW0pIHsgcmV0dXJuIHBhcmFtLno7IH0KfQoKdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHR5cGVuYW1lID0gdm9pZD4KY29uc3RleHByIGRldGFpbHM6OnN1YnNjcmlwdF9mdW5jdGlvbjxUPiBteV90ZW1wW10gPSB7ICZkZXRhaWxzOjpYPFQ+LCAmZGV0YWlsczo6WTxUPiB9OwoKdGVtcGxhdGUgPHR5cGVuYW1lIFQ+CmNvbnN0ZXhwciBkZXRhaWxzOjpzdWJzY3JpcHRfZnVuY3Rpb248VD4gbXlfdGVtcDxULCBlbmFibGVfaWZfdDxpc19mbG9hdGluZ19wb2ludDxkZWNsdHlwZShkZXRhaWxzOjpYKFQoKSkpPjo6dmFsdWUsIFQ+PltdID0geyAmZGV0YWlsczo6WDxUPiwgJmRldGFpbHM6Olk8VD4sICZkZXRhaWxzOjpaPFQ+IH07CgoKaW50IG1haW4oKSB7CiAgdmVjIGZvbyA9IHsgMS4wLCAyLjAsIDMuMCB9OwoKICBmb3IoY29uc3QgYXV0byBpIDogbXlfdGVtcDxkZWNsdHlwZShmb28pPikgewogICAgY291dCA8PCAoKmkpKGZvbykgPDwgZW5kbDsKICB9Cn0=