#include <iostream>
using namespace std;

// Test struct.
template<class T>
struct Foo
{
    T foo;
};

// Struct specialization
template<>
struct Foo<bool>
{
    static const int val = 46;
};

// #1 Ordinary template
template<class T>
struct functionWrapper {
	static T foo() {
		return T();
	}
};


// #2 Template specialization
template<>
struct functionWrapper<int> {
	static int foo() {
		return 42;
	}
};


// #3 Template specialization with template as parameter
template<class T>
struct functionWrapper<struct Foo<T>> {
	static Foo<T>* foo() {
		return new Foo<T>();
	}
};





int main() {
	cout << functionWrapper<bool>::foo() << endl;
	cout << functionWrapper<int>::foo() << endl;
	
	Foo<bool> *obj = functionWrapper<Foo<bool>>::foo();
	cout << obj->val;
	delete obj;
	
	return 0;
}