#include <string>
#include <iostream>
template<typename Ret>
Ret foo(const char *,int);
template<>
std::string foo<std::string>(const char *s,int) { return s; }
template<>
int foo<int >(const char *,int i) { return i; }
#include<tuple>
template<size_t num_args, typename ...T>
class Foo;
template<typename ...T>
class Foo<2,T...> : public std::tuple<T&&...>
{
public:
Foo(T&&... args) :
std::tuple<T&&...>(std::forward<T>(args)...)
{}
template< typename Return >
operator Return() { return foo<Return>(std::get<0>(*this), std::get<1>(*this)); }
};
template<typename ...T>
class Foo<3,T...> : std::tuple<T&&...>
{
public:
Foo(T&&... args) :
std::tuple<T&&...>(std::forward<T>(args)...)
{}
template< typename Return >
operator Return() { return foo<Return>(std::get<0>(*this), std::get<1>(*this), std::get<2>(*this)); }
};
template<typename ...T>
auto
auto_foo(T&&... args)
// -> Foo<T&&...> // old, incorrect, code
-> Foo< sizeof...(T), T&&...> // to count the arguments
{
return {std::forward<T>(args)...};
}
int main() {
std::string s = auto_foo("hi",5); std::cout << s << std::endl;
int i = auto_foo("hi",5); std::cout << i << std::endl;
}
I2luY2x1ZGUgPHN0cmluZz4KI2luY2x1ZGUgPGlvc3RyZWFtPgoKdGVtcGxhdGU8dHlwZW5hbWUgUmV0PgpSZXQgZm9vKGNvbnN0IGNoYXIgKixpbnQpOwp0ZW1wbGF0ZTw+CnN0ZDo6c3RyaW5nIGZvbzxzdGQ6OnN0cmluZz4oY29uc3QgY2hhciAqcyxpbnQpIHsgcmV0dXJuIHM7IH0KdGVtcGxhdGU8PgppbnQgICAgICAgICBmb288aW50ICAgICAgICA+KGNvbnN0IGNoYXIgKixpbnQgaSkgeyByZXR1cm4gaTsgfQoKCiNpbmNsdWRlPHR1cGxlPgoKdGVtcGxhdGU8c2l6ZV90IG51bV9hcmdzLCB0eXBlbmFtZSAuLi5UPgpjbGFzcyBGb287CnRlbXBsYXRlPHR5cGVuYW1lIC4uLlQ+CmNsYXNzIEZvbzwyLFQuLi4+IDogcHVibGljIHN0ZDo6dHVwbGU8VCYmLi4uPgp7CnB1YmxpYzogCiAgICAgICAgRm9vKFQmJi4uLiBhcmdzKSA6CiAgICAgICAgICAgICAgICBzdGQ6OnR1cGxlPFQmJi4uLj4oc3RkOjpmb3J3YXJkPFQ+KGFyZ3MpLi4uKQogICAgICAgIHt9CiAgICAgICAgdGVtcGxhdGU8IHR5cGVuYW1lIFJldHVybiA+CiAgICAgICAgb3BlcmF0b3IgUmV0dXJuKCkgeyByZXR1cm4gZm9vPFJldHVybj4oc3RkOjpnZXQ8MD4oKnRoaXMpLCBzdGQ6OmdldDwxPigqdGhpcykpOyB9Cn07CnRlbXBsYXRlPHR5cGVuYW1lIC4uLlQ+CmNsYXNzIEZvbzwzLFQuLi4+IDogc3RkOjp0dXBsZTxUJiYuLi4+CnsKcHVibGljOiAKICAgICAgICBGb28oVCYmLi4uIGFyZ3MpIDoKICAgICAgICAgICAgICAgIHN0ZDo6dHVwbGU8VCYmLi4uPihzdGQ6OmZvcndhcmQ8VD4oYXJncykuLi4pCiAgICAgICAge30KICAgICAgICB0ZW1wbGF0ZTwgdHlwZW5hbWUgUmV0dXJuID4KICAgICAgICBvcGVyYXRvciBSZXR1cm4oKSB7IHJldHVybiBmb288UmV0dXJuPihzdGQ6OmdldDwwPigqdGhpcyksIHN0ZDo6Z2V0PDE+KCp0aGlzKSwgc3RkOjpnZXQ8Mj4oKnRoaXMpKTsgfQp9OwoKdGVtcGxhdGU8dHlwZW5hbWUgLi4uVD4KYXV0bwphdXRvX2ZvbyhUJiYuLi4gYXJncykKICAgICAgICAvLyAtPiBGb288VCYmLi4uPiAvLyBvbGQsIGluY29ycmVjdCwgY29kZQogICAgICAgIC0+IEZvbzwgc2l6ZW9mLi4uKFQpLCBUJiYuLi4+IC8vIHRvIGNvdW50IHRoZSBhcmd1bWVudHMKewogICAgICAgIHJldHVybiAgICAgICAgICAgICAge3N0ZDo6Zm9yd2FyZDxUPihhcmdzKS4uLn07Cn0KCgoKCmludCBtYWluKCkgewogICAgICAgIHN0ZDo6c3RyaW5nIHMgPSBhdXRvX2ZvbygiaGkiLDUpOyBzdGQ6OmNvdXQgPDwgcyA8PCBzdGQ6OmVuZGw7CiAgICAgICAgaW50ICAgICAgICAgaSA9IGF1dG9fZm9vKCJoaSIsNSk7IHN0ZDo6Y291dCA8PCBpIDw8IHN0ZDo6ZW5kbDsKfQ==