#include <functional>
#include <iostream>
#include <typeinfo>
using namespace std;
template <typename T1, typename T2> class Test {
public:
Test() { cout << "main" << endl; }
};
template <typename T1, typename T2> class Test<T1*, T2*> {
public:
Test() { cout << "specialization" << endl; }
};
template <typename T2> class Test<int, T2> {
public:
Test() { cout << "partial specialization 1" << endl; }
};
template <> class Test<int, double> {
public:
Test() { cout << "partial specialization 2" << endl; }
};
template <typename T1, typename T2> void func1(T1 t1, T2 t2) {
cout << "main : " << typeid(t1).name() << ", " << typeid(t2).name() << endl;
}
template <typename T1, typename T2> void func1(T1* t1, T2* t2) {
cout << "specialization" << endl;
}
template <typename T2> void func1(int t1, T2 t2) {
cout << "partial specialization 1" << endl;
}
template <> void func1(int t1, double t2) { cout << "partial specialization 2" << endl; }
template <int i> void func1() { cout << i << endl; }
template <typename T = int> void func2(T t) { cout << typeid(t).name() << endl; }
template <typename T, int add> void func3(T t, int i) { t(i + add); }
template <typename T, int add = 5> void func4(T t, int i) { t(i + add); }
template <typename Type> void func5(Type t) { cout << t << endl; }
template <typename Type, typename... Types> void func5(Type t, Types... ts) {
cout << t << ", ";
func5(ts...);
}
template <typename... Types> void func6(Types... ts) { cout << sizeof...(ts) << endl; }
template <typename Type, typename... Types> void func7(Type t, Types... ts) {
cout << (... + ts) << endl;
cout << (ts - ...) << endl;
cout << (t + ... + ts) << endl;
auto f = [](int i) { cout << i << endl; };
(f(ts), ...);
}
int factorial_recursion(int n) {
if (n == 0) {
return 1;
}
return n * factorial_recursion(n - 1);
}
template <int N> struct Factorial_TMP {
enum { value = N * Factorial_TMP<N - 1>::value };
};
template <> struct Factorial_TMP<0> {
enum { value = 1 };
};
int main() {
Test<char, int>();
Test<int*, char*>();
Test<int, char>();
Test<int, double>();
cout << "------" << endl;
func1('c', 1);
func1(new int(1), new char('c'));
func1(1, 'c');
func1(1, 1.1);
func1<5>();
cout << "------" << endl;
func2(1);
func2<double>(1);
cout << "------" << endl;
function<void(int)> f = [](int i) { cout << i << endl; };
func3<function<void(int)>, 1>(f, 1);
func3<function<void(int)>, 2>(f, 1);
func4(f, 1);
cout << "------" << endl;
func5(1, 'a');
func5("abc", 1.1, "!");
cout << "------" << endl;
func6(1);
func6(1, 'a');
cout << "------" << endl;
func7(1, 2, 3);
cout << "------" << endl;
cout << factorial_recursion(10) << endl;
cout << Factorial_TMP<10>::value << endl;
return 0;
}