派生クラスのC ++型のタイプリスト
-
13-12-2019 - |
質問
CRTP(不思議な繰り返しテンプレートパターン)を使用すると、それから派生したクラスに関する知識を持つ基本クラスを提供できます。基本クラスから派生する各クラスのインスタンスを格納するアレイを作成することは難しくありません(例を参照)
class Base{
public:
static std::vector<Base *> m_derivedInstances;
};
template <class Derived>
class CRTPBase : public Base {
public:
static bool m_temp;
static bool addInstance()
{
m_derivedInstances.push_back(new Derived);
return true;
}
};
template <class Derived>
CRTPBase<Derived>::m_temp = CRTPBase<Derived>::addInstance();
.
私はTypeListを作成することが可能であるかどうか疑問に思っていました( http ://www.research.ibm.com/designpatterns/pubs/ph-jun00.pdf )派生クラスのすべてのタイプの。問題は、CompillerがBase
から派生する新しいクラスを表示するたびに、リストに新しいタイプを追加する必要がありますが、TypeListは不変です(新しいタイプを追加することで新しいリストを作成することは可能ですが、それに追加することは可能です。リストに要素を追加することは私が知っている限り不可能です。最後に、私はこのようなものを持っていたいです:
struct DerivedClassHolder {
typedef Loki::TL::MakeTypeList</*list all derived classes here*/>::Result DerivedTypes;
};
.
究極の目標は、Base
から派生するすべてのクラスを繰り返すことができることです。
解決
疑似タイプマップを使用して行うことができます。これはBoost :: MPLを使用したコード例です。「IMPLEM」の明示的な定義は、それぞれの対応する個人用ヘッダーのマクロで行うことができます。
#include <iostream>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/for_each.hpp>
#include <boost/mpl/push_front.hpp>
#include <boost/mpl/empty_sequence.hpp>
#include <boost/type_traits/is_same.hpp>
using namespace boost::mpl;
using namespace boost;
// A type map. Implem #N of type Key is type (default: void)
template <typename Key, int N>
struct Implem
{
public:
typedef void type;
};
// Type vector building functions
// void, the default type, is used to stop the recursion
template <typename Key, int N = 1>
struct ImplemToList;
template <typename Key, typename Item, int N>
struct ImplemListItem
{
public:
typedef typename push_front<typename ImplemToList<Key, N + 1>::type, Item>::type type;
};
template <typename Key, int N>
struct ImplemToList
{
public:
typedef typename Implem<Key, N>::type item;
typedef typename eval_if<is_same<item, void>,
identity<vector<> >,
ImplemListItem<Key, item, N> >::type type;
};
// Example code: an interface with two implems
class Interface
{
public:
virtual const char* name() const = 0;
};
class Implem1 : public Interface
{
public:
virtual const char* name() const { return "implem_1"; }
};
class Implem2 : public Interface
{
public:
virtual const char* name() const { return "implem_2"; }
};
template <>
struct Implem<Interface, 1>
{
public:
typedef Implem1 type;
};
template <>
struct Implem<Interface, 2>
{
public:
typedef Implem2 type;
};
void print(Interface const& i)
{
std::cout << i.name() << std::endl;
}
int main()
{
typedef ImplemToList<Interface>::type IList;
for_each<IList>(&print);
}
. 他のヒント
あなたのTypeListは手でのみ作成できます。あなたが言及した問題、不変性は絶滅可能です。
所属していません StackOverflow