#include <utility>
#include <iostream>
template <int N, typename FirstArg, typename... Args>
struct NthArgHelper {
static_assert(N > 0, "N should be positive");
static_assert(N < sizeof...(Args) + 1, "N is too large");
typedef typename NthArgHelper<N - 1, Args...>::Type Type;
static Type&& get(FirstArg&&, Args&&... args) {
return NthArgHelper<N - 1, Args...>::get(args...);
}
};
template <typename FirstArg, typename... Args>
struct NthArgHelper<0, FirstArg, Args...> {
typedef FirstArg Type;
static Type&& get(FirstArg&& arg, Args&&...) {
return std::forward<FirstArg>(arg);
}
};
template <int N, typename... Args>
typename NthArgHelper<N, Args...>::Type&& NthArg(Args&&... args)
{
return NthArgHelper<N, Args...>::get(args...);
}
template <typename... Args>
void test(Args&&... args) {
std::cout << "Argument 2: " << NthArg<2>(args...) << std::endl;
std::cout << "Argument 0: " << NthArg<0>(args...) << std::endl;
}
int main() {
test(10, 3.1415, "Hello!");
std::cout << "=======================\n";
test(1, 2, 3, 7, 9, 5, 6, 6);
return 0;
}
I2luY2x1ZGUgPHV0aWxpdHk+CiNpbmNsdWRlIDxpb3N0cmVhbT4KCgp0ZW1wbGF0ZSA8aW50IE4sIHR5cGVuYW1lIEZpcnN0QXJnLCB0eXBlbmFtZS4uLiBBcmdzPgpzdHJ1Y3QgTnRoQXJnSGVscGVyIHsKICAgIHN0YXRpY19hc3NlcnQoTiA+IDAsICJOIHNob3VsZCBiZSBwb3NpdGl2ZSIpOwogICAgc3RhdGljX2Fzc2VydChOIDwgc2l6ZW9mLi4uKEFyZ3MpICsgMSwgIk4gaXMgdG9vIGxhcmdlIik7CgogICAgdHlwZWRlZiB0eXBlbmFtZSBOdGhBcmdIZWxwZXI8TiAtIDEsIEFyZ3MuLi4+OjpUeXBlIFR5cGU7CgogICAgc3RhdGljIFR5cGUmJiBnZXQoRmlyc3RBcmcmJiwgQXJncyYmLi4uIGFyZ3MpIHsKICAgICAgICByZXR1cm4gTnRoQXJnSGVscGVyPE4gLSAxLCBBcmdzLi4uPjo6Z2V0KGFyZ3MuLi4pOwogICAgfQp9OwoKdGVtcGxhdGUgPHR5cGVuYW1lIEZpcnN0QXJnLCB0eXBlbmFtZS4uLiBBcmdzPgpzdHJ1Y3QgTnRoQXJnSGVscGVyPDAsIEZpcnN0QXJnLCBBcmdzLi4uPiB7CiAgICB0eXBlZGVmIEZpcnN0QXJnIFR5cGU7CgogICAgc3RhdGljIFR5cGUmJiBnZXQoRmlyc3RBcmcmJiBhcmcsIEFyZ3MmJi4uLikgewogICAgICAgIHJldHVybiBzdGQ6OmZvcndhcmQ8Rmlyc3RBcmc+KGFyZyk7CiAgICB9Cn07Cgp0ZW1wbGF0ZSA8aW50IE4sIHR5cGVuYW1lLi4uIEFyZ3M+CnR5cGVuYW1lIE50aEFyZ0hlbHBlcjxOLCBBcmdzLi4uPjo6VHlwZSYmIE50aEFyZyhBcmdzJiYuLi4gYXJncykKewogICAgcmV0dXJuIE50aEFyZ0hlbHBlcjxOLCBBcmdzLi4uPjo6Z2V0KGFyZ3MuLi4pOwp9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUuLi4gQXJncz4Kdm9pZCB0ZXN0KEFyZ3MmJi4uLiBhcmdzKSB7CiAgICBzdGQ6OmNvdXQgPDwgIkFyZ3VtZW50IDI6ICIgPDwgTnRoQXJnPDI+KGFyZ3MuLi4pIDw8IHN0ZDo6ZW5kbDsKICAgIHN0ZDo6Y291dCA8PCAiQXJndW1lbnQgMDogIiA8PCBOdGhBcmc8MD4oYXJncy4uLikgPDwgc3RkOjplbmRsOwp9CgppbnQgbWFpbigpIHsKICAgdGVzdCgxMCwgMy4xNDE1LCAiSGVsbG8hIik7CiAgIHN0ZDo6Y291dCA8PCAiPT09PT09PT09PT09PT09PT09PT09PT1cbiI7CiAgIHRlc3QoMSwgMiwgMywgNywgOSwgNSwgNiwgNik7CiAgIHJldHVybiAwOwp9