#include <iostream>
#include <tuple>
using namespace std;
template<typename ... Types> void foo(Types ... args)
{
  int x[] = { args... };  // 그런데 타입이 다르다면?
  tuple<Types...> tp(args...);  // tuple을 쓰자
  
  cout << get<0>(tp) << endl;
  cout << get<1>(tp) << endl;
  cout << get<2>(tp) << endl;
  
  // 다른 방버은 없나?
}
int main()
{
  foo(1, 3.4, "AA");
}
void foo() {} // 재귀의 종료를 위해
template<typename T, typename ... Types> 
void foo(T value, Types ... args)
{
  cout << value << endl;
  // 재귀적 호출(but 코드상으론 여러 함수가 생성됨을 기억)
  foo(args...);
}
int main()
{
  foo(1, 3.4, "AA");
}
fold expression
#include <iostream>
using namespace std;
template<typename ... Types>
int foo(Types ... args)
{
  int x[] = { args... };  // pack expansion
  
  int n = ( args + ... );   // fold expression -> 다른 기능도 있지만 필요하면 찾아서 쓰자.
  // 1+(2+(3+4))
  
  return 0;
}
int main()
{
  int n = foo(1, 2, 3, 4);
}
example
template<typename ... Types>
void foo(Types ... args)
{
  ( cout << ... << args );
  // ((( cout << 1) << 2 ) << 3);
}
int main()
{
  cout << 1 << 2 << 3;
  // (((cout << 1) << 2) << 3);
  
  foo(1, 2, 3);
}
vector<int> v;
template<typename ... Types>
void foo(Types .. args)
{
  ( args, ... );  
  // 1, (2, 3)
  
  ( v.push_back(args), ... );
  // v.push_back(1), (v.push_back(2), v.push_back(3));
  
  for(auto n : v)
    cout << n << endl;
}
int main()
{
  foo(1, 2, 3);
}
example - 재귀용법
#include <iostream>
#include <tuple>
using namespace std;
template<typename ... Types> void foo(Types ... args)
{
    tuple<Types ...> tp(args...);
    cout << get<0>(tp) << endl;
    cout << get<1>(tp) << endl;
    cout << get<2>(tp) << endl;
}
int main()
{
    foo(1, 3.4, "AA");  // args : 1, 3.4, "AA"
}
#include <iostream>
#include <tuple>
using namespace std;
void foo() {}   // 재귀의 종료를 위해서
template<typename T, typename ... Types>
void foo(T value, Types ... args)
{
    cout << value << endl;      // 1
    foo(args...);               // 이런식으로 recursive하게 호출해서 쓰는 방법!
}
int main()
{
    foo(1, 3.4, "AA");
}