It's wrong you explicit specialize like this, this is because TT1, TT2 and TT3 is same thing before you instantiate it. to fix this problem, you have to try other ways
e.g.
Code:
template<typename _Target> int match(_Target**);
template<typename _Target> char match(...);
template<typename _T, typename _U>
struct same_type
{
enum{ value = sizeof(int) == sizeof(match<_T>((_U**)0))};
};
template<bool _Cond, typename _True, typename _False>
struct _if
{
typedef _True value_type;
};
template<typename _True, typename _False>
struct _if<false, _True, _False>
{
typedef _False value_type;
};
template<int ID>
struct IntToType{ enum {value = ID}; };
template < class T,
template <typename> class TT1,
template <typename> class TT2,
template <typename> class TT3>
struct Container
{
typedef TT1<T> T1;
typedef TT2<T> T2;
typedef TT3<T> T3;
template <template <typename> class FTT>
FTT<T> object()
{
typedef FTT<T> type;
return __object<_if<same_type<T1, type>::value,
IntToType<1>,
typename _if<same_type<T2, type>::value,
IntToType<2>,
typename _if<same_type<T3, type>::value,
IntToType<3>,
IntToType<0>
>::value_type
>::value_type
>::value_type::value, FTT<T> >::get(*this);
}
template<int _ID, typename _T>
struct __object
{
static _T get(Container&){ return _T(); };
};
template<typename _T>
struct __object<1, _T>
{
static TT1<T> get(Container& c){ return c.object1_; }
};
template<typename _T>
struct __object<2, _T>
{
static TT2<T> get(Container& c){ return c.object2_; }
};
template<typename _T>
struct __object<3, _T>
{
static TT3<T> get(Container& c){ return c.object3_; }
};
private:
TT1<T> object1_;
TT2<T> object2_;
TT3<T> object3_;
};
template<class T> struct X{ /* omitted*/ };
template<class T> struct Y{ /* omitted*/ };
template<class T> struct Z{ /* omitted*/ };
int main()
{
Container<int, X, Y, Z> container;
X<int> result1 = container.object<X>();
Y<int> result2 = container.object<Y>();
Z<int> result3 = container.object<Z>();
std::system("pause");
}