読者です 読者をやめる 読者になる 読者になる

C++と色々

主にC++やプログラムに関する記事を投稿します。

型特性メタ関数(おまけ)

前回の記事の続き。やっぱりboost使ってない版も書いてみた

#include <iostream>
using std::cout;
using std::endl;

//基底クラス:ガンダム
class Gundam
{
};

//ガンダム派生クラス:エクシア
class Exia : public Gundam
{
};

//ガンダム派生クラス:ゴッド
class God : public Gundam
{
};

//ザク
class Zaku
{
};

//ガンダムか判定するメタ関数
template <class T>
class IsGundam
{
	static char Test(Gundam);
	static double Test(...);
	
	static T CreateT();

public:
	static const bool value = sizeof(Test(CreateT())) == sizeof(char);
};

//真ならオーバーロードできる
template<bool b, class T = void>
class ConstEnableIf
{
public:
	typedef T* Type;
};

template<class T>
class ConstEnableIf<false, T>
{
};

template<class Cond, class T = void>
class EnableIf : public ConstEnableIf<Cond::value>
{
};

//偽ならオーバーロードできる
template<bool b, class T = void>
class ConstDisableIf
{
public:
	typedef T* Type;
};

template<class T>
class ConstDisableIf<true, T>
{
};

template<class Cond, class T = void>
class DisableIf : public ConstDisableIf<Cond::value>
{
};

//チェック関数
template<class T>
void Check(T value, typename EnableIf<IsGundam<T>>::Type* = 0)
{
	cout << typeid(value).name() << "は、ガンダムだ!!!" << endl;
}

template<class T>
void Check(T value, typename DisableIf<IsGundam<T>>::Type* = 0)
{
	cout << typeid(value).name() << "は、ガンダムではない!!!" << endl;
}


int main()
{
	Check(Gundam());//ガンダム
	Check(Exia());//ガンダム
	Check(God());//ガンダム
	Check(Zaku());//ガンダムではない
	Check(int());//ガンダムではない
	return 0;
}