#include <type_traits>
#include <typeinfo>
#include <iostream>
template<typename T, typename ... Ts>
struct are_arithmetic{
enum {
value = std::is_arithmetic<T>::value && are_arithmetic<Ts...>::value
};
};
template<typename T>
struct are_arithmetic<T>{
enum {
value = std::is_arithmetic<T>::value
};
};
template<typename Arg, typename = typename std::enable_if<std::is_arithmetic<Arg>::value>::type>
Arg max(Arg arg){
return arg;
}
template<typename Arg, typename Arg1, typename ... Args, typename = typename std::enable_if<are_arithmetic<Arg, Arg1, Args...>::value>::type>
auto max(Arg arg, Arg1 arg1, Args ... args){
auto max_rest = max(arg1, args...);
return arg > max_rest ? arg : max_rest;
}
int main(){
auto res = max(1.0, 2, 3.0f, 5, 7l);
std::cout << typeid(res).name() << " " << typeid(7l).name();
}
I2luY2x1ZGUgPHR5cGVfdHJhaXRzPgojaW5jbHVkZSA8dHlwZWluZm8+CiNpbmNsdWRlIDxpb3N0cmVhbT4KdGVtcGxhdGU8dHlwZW5hbWUgVCwgdHlwZW5hbWUgLi4uIFRzPgpzdHJ1Y3QgYXJlX2FyaXRobWV0aWN7CiAgICBlbnVtIHsKICAgICAgICB2YWx1ZSA9IHN0ZDo6aXNfYXJpdGhtZXRpYzxUPjo6dmFsdWUgJiYgYXJlX2FyaXRobWV0aWM8VHMuLi4+Ojp2YWx1ZQogICAgfTsKfTsKCnRlbXBsYXRlPHR5cGVuYW1lIFQ+CnN0cnVjdCBhcmVfYXJpdGhtZXRpYzxUPnsKICAgIGVudW0gewogICAgICAgIHZhbHVlID0gc3RkOjppc19hcml0aG1ldGljPFQ+Ojp2YWx1ZQogICAgfTsKfTsKCnRlbXBsYXRlPHR5cGVuYW1lIEFyZywgdHlwZW5hbWUgPSB0eXBlbmFtZSBzdGQ6OmVuYWJsZV9pZjxzdGQ6OmlzX2FyaXRobWV0aWM8QXJnPjo6dmFsdWU+Ojp0eXBlPgpBcmcgbWF4KEFyZyBhcmcpewogICAgcmV0dXJuIGFyZzsKfQoKdGVtcGxhdGU8dHlwZW5hbWUgQXJnLCB0eXBlbmFtZSBBcmcxLCB0eXBlbmFtZSAuLi4gQXJncywgdHlwZW5hbWUgPSB0eXBlbmFtZSBzdGQ6OmVuYWJsZV9pZjxhcmVfYXJpdGhtZXRpYzxBcmcsIEFyZzEsIEFyZ3MuLi4+Ojp2YWx1ZT46OnR5cGU+CmF1dG8gbWF4KEFyZyBhcmcsIEFyZzEgYXJnMSwgQXJncyAuLi4gYXJncyl7CiAgICBhdXRvIG1heF9yZXN0ID0gbWF4KGFyZzEsIGFyZ3MuLi4pOwogICAgcmV0dXJuIGFyZyA+IG1heF9yZXN0ID8gYXJnIDogbWF4X3Jlc3Q7Cn0KCmludCBtYWluKCl7CiAgICBhdXRvIHJlcyA9IG1heCgxLjAsIDIsIDMuMGYsIDUsIDdsKTsKICAgIHN0ZDo6Y291dCA8PCB0eXBlaWQocmVzKS5uYW1lKCkgPDwgIiAiICA8PCB0eXBlaWQoN2wpLm5hbWUoKTsKfQ==