gpt4 book ai didi

c++派生类的类型列表

转载 作者:搜寻专家 更新时间:2023-10-31 00:43:23 25 4
gpt4 key购买 nike

使用 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();

我想知道是否可以创建一个包含所有派生类类型的类型列表(请参阅 http://www.research.ibm.com/designpatterns/pubs/ph-jun00.pdf)。问题在于,每次编译器看到一个派生自 Base 的新类时,它都需要将一个新类型附加到列表中,但是类型列表是不可变的(可以使用新类型附加到它,但据我所知,向列表添加元素是不可能的。最后我想要这样的东西:

struct DerivedClassHolder {
typedef Loki::TL::MakeTypeList</*list all derived classes here*/>::Result DerivedTypes;
};

最终目标是能够遍历从 Base 派生的所有类。

最佳答案

可以使用伪类型映射来完成。下面是一些使用 boost::mpl 的示例代码。 “Implem”的显式定义可以在每个相应的 implem header 中使用宏来完成。

#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);
}

关于c++派生类的类型列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10707552/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com