#include <iostream>
#include <typeinfo>
#include <type_traits>
using namespace std;
struct A {
A() {}
A(const A& a) { cout << "Copy Constructed " << __func__ << endl; }
A(A&& a) { cout << "Move Constructed " << __func__ << endl; }
};
struct B {
B() {}
B(const B& b) { cout << "Copy Constructed " << __func__ << endl; }
B(B&& b) { cout << "Move Constructed " << __func__ << endl; }
};
template <typename... T> struct MultiTypes;
template <typename T1, typename... T>
struct MultiTypes<T1, T...> : public MultiTypes<T...> {
T1 t1;
MultiTypes<T1, T...>(T1 a, T... b) : t1(a), MultiTypes<T...>(b...) {
cout << "get inside " << __func__ << endl;
cout << "MultiTypes<T1, T...>(T1 a, T... b)" << endl;
}
};
template<>
struct MultiTypes<> {
MultiTypes<>() { cout << "get inside final MultiTypes()"<< endl;
cout << "MultiTypes<>()" << endl; }
};
template <template <typename...> class VariadicType, typename... Args>
VariadicType<Args...> Build(Args&&... args)
{
cout << "get inside " << __func__ << endl;
return VariadicType<Args...>(forward<Args>(args)...);
}
template <template <typename...> class VariadicType, typename... Args>
VariadicType<Args...> NewBuild(Args... args)
{
cout << "get inside " << __func__ << endl;
return VariadicType<Args...>(forward<Args>(args)...);
}
int main()
{
A a;
B b;
cout << typeid(Build<MultiTypes>(a, b)).name() << endl;
MultiTypes<A&, B&> c = Build<MultiTypes>(a, b);
cout << typeid(c.t1).name() << endl;
MultiTypes<A, B> d = NewBuild<MultiTypes>(a, b);
return 0;
}
