#include <iostream>
#include <string>
template <std::size_t Index, typename first, typename ...remaining>
struct type_at
{
typedef typename type_at<Index - 1, remaining...>::type type;
};
template <typename first, typename ...remaining>
struct type_at<0, first, remaining...>
{
typedef first type;
};
template <std::size_t Index, typename first, typename ...remaining>
struct value_at
{
static typename type_at<Index, first, remaining...>::type
get(first First, remaining... args)
{
return value_at<Index - 1, remaining...>::get(args...);
}
};
template <typename first, typename ...remaining>
struct value_at<0, first, remaining...>
{
static first get(first First, remaining...)
{
return First;
}
};
template <std::size_t Index, typename T, typename ...Args>
typename type_at<Index, T, Args...>::type
get(T t1, Args... args)
{
return
static_cast<type_at<Index, T, Args...>::type>
(
reinterpret_cast<void*>
(
value_at<Index, T, Args...>::get(t1, args...)
)
);
}
int main()
{
int * a = new int(10);
double* b = new double(3.14);
std::string c = "But I'm a string :(";
std::cout<< *get<0>(a, b, &c) <<"\n";
std::cout<< *get<1>(a, b, &c) <<"\n";
std::cout<< *get<2>(a, b, &c) <<"\n";
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3RyaW5nPgoKdGVtcGxhdGUgPHN0ZDo6c2l6ZV90IEluZGV4LCB0eXBlbmFtZSBmaXJzdCwgdHlwZW5hbWUgLi4ucmVtYWluaW5nPgpzdHJ1Y3QgdHlwZV9hdAp7CiAgICB0eXBlZGVmIHR5cGVuYW1lIHR5cGVfYXQ8SW5kZXggLSAxLCByZW1haW5pbmcuLi4+Ojp0eXBlIHR5cGU7Cn07Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgZmlyc3QsIHR5cGVuYW1lIC4uLnJlbWFpbmluZz4Kc3RydWN0IHR5cGVfYXQ8MCwgZmlyc3QsIHJlbWFpbmluZy4uLj4KewoJdHlwZWRlZiBmaXJzdCB0eXBlOwp9OwoKdGVtcGxhdGUgPHN0ZDo6c2l6ZV90IEluZGV4LCB0eXBlbmFtZSBmaXJzdCwgdHlwZW5hbWUgLi4ucmVtYWluaW5nPgpzdHJ1Y3QgdmFsdWVfYXQKewoJc3RhdGljIHR5cGVuYW1lIHR5cGVfYXQ8SW5kZXgsIGZpcnN0LCByZW1haW5pbmcuLi4+Ojp0eXBlIAoJZ2V0KGZpcnN0IEZpcnN0LCByZW1haW5pbmcuLi4gYXJncykKCXsKCQlyZXR1cm4gdmFsdWVfYXQ8SW5kZXggLSAxLCByZW1haW5pbmcuLi4+OjpnZXQoYXJncy4uLik7Cgl9Cn07Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgZmlyc3QsIHR5cGVuYW1lIC4uLnJlbWFpbmluZz4Kc3RydWN0IHZhbHVlX2F0PDAsIGZpcnN0LCByZW1haW5pbmcuLi4+CnsKCXN0YXRpYyBmaXJzdCBnZXQoZmlyc3QgRmlyc3QsIHJlbWFpbmluZy4uLikKCXsKCQlyZXR1cm4gRmlyc3Q7Cgl9Cn07Cgp0ZW1wbGF0ZSA8c3RkOjpzaXplX3QgSW5kZXgsIHR5cGVuYW1lIFQsIHR5cGVuYW1lIC4uLkFyZ3M+CnR5cGVuYW1lIHR5cGVfYXQ8SW5kZXgsIFQsIEFyZ3MuLi4+Ojp0eXBlCmdldChUIHQxLCBBcmdzLi4uIGFyZ3MpCnsKCXJldHVybiAKCQlzdGF0aWNfY2FzdDx0eXBlX2F0PEluZGV4LCBULCBBcmdzLi4uPjo6dHlwZT4KCQkoCgkJCXJlaW50ZXJwcmV0X2Nhc3Q8dm9pZCo+CgkJCSgKCQkJCXZhbHVlX2F0PEluZGV4LCBULCBBcmdzLi4uPjo6Z2V0KHQxLCBhcmdzLi4uKQoJCQkpCgkJKTsKfQoKCmludCBtYWluKCkKewoJaW50ICAgKiBhICAgICA9IG5ldyBpbnQoMTApOwoJZG91YmxlKiBiICAgICA9IG5ldyBkb3VibGUoMy4xNCk7CglzdGQ6OnN0cmluZyBjID0gIkJ1dCBJJ20gYSBzdHJpbmcgOigiOwoKCXN0ZDo6Y291dDw8ICpnZXQ8MD4oYSwgYiwgJmMpIDw8IlxuIjsKCXN0ZDo6Y291dDw8ICpnZXQ8MT4oYSwgYiwgJmMpIDw8IlxuIjsKCXN0ZDo6Y291dDw8ICpnZXQ8Mj4oYSwgYiwgJmMpIDw8IlxuIjsKfQ==
prog.cpp: In function ‘typename type_at<Index, first, remaining>::type get(T, Args ...)’:
prog.cpp:40:15: error: expected type-specifier
static_cast<type_at<Index, T, Args...>::type>
^
prog.cpp:40:15: error: expected ‘>’
prog.cpp:40:15: error: expected ‘(’
prog.cpp:46:4: error: expected ‘)’ before ‘;’ token
);
^
prog.cpp: In function ‘typename type_at<Index, first, remaining>::type get(T, Args ...) [with unsigned int Index = 0u; T = int*; Args = {double*, std::basic_string<char, std::char_traits<char>, std::allocator<char> >*}; typename type_at<Index, first, remaining>::type = int*]’:
prog.cpp:47:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
prog.cpp: In function ‘typename type_at<Index, first, remaining>::type get(T, Args ...) [with unsigned int Index = 1u; T = int*; Args = {double*, std::basic_string<char, std::char_traits<char>, std::allocator<char> >*}; typename type_at<Index, first, remaining>::type = double*]’:
prog.cpp:47:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
prog.cpp: In function ‘typename type_at<Index, first, remaining>::type get(T, Args ...) [with unsigned int Index = 2u; T = int*; Args = {double*, std::basic_string<char, std::char_traits<char>, std::allocator<char> >*}; typename type_at<Index, first, remaining>::type = std::basic_string<char>*]’:
prog.cpp:47:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^