C ++ meta编程创建一个新的类型列表,其中remove_const应用于每个元素

时间:2010-04-14 05:12:54

标签: c++ metaprogramming

嗨,任何人都可以给我一个示例程序“创建一个ApplyRemoveConst模板 构造一个新的类型列表,其中remove_const应用于每个元素“

例如:

typedef TYPELIST_3(A, const B, B) TL;
typedef ApplyRemoveConst<TL>::Result TL2;
// TL2 is the same as TYPELIST_3(A, B, B)


//Typelist Definition:

template<class T, class U>
struct Typelist
{
    typedef T Head;
    typedef U Tail;
    // Lets us a print a typelist
    inline static ostream &print(ostream &os) {
        return printInternal(os, "[");
    }
    inline static ostream &printInternal(ostream &os, string delimiter) {
        os << delimiter << typeid(Head).name();
        return Tail::printInternal(os, ", ");
    }
private:
    Typelist(); // Cannot create!
};

#define TYPELIST_1(T1)  Typelist<T1, NullType>
#define TYPELIST_2(T1, T2) Typelist<T1, TYPELIST_1(T2)>
#define TYPELIST_3(T1, T2, T3) Typelist<T1, TYPELIST_2(T2, T3)>

// Null type definition 

class NullType{
public:
    // NullType ends a typelist (just like NULL ends a C string)
    inline static ostream &printInternal(ostream &os, string delimiter) {
        return os << "]";
    }
};

1 个答案:

答案 0 :(得分:4)

我认为你想要的是这样的:

template <typename, template <typename> class>
struct transform;

template <template <typename> class Func>
struct transform<NullType, Func>
{
    typedef NullType type; // nothing to do
};

template <typename T, typename U, template <typename> class Func>
struct transform<Typelist<T, U>, Func>
{
    typedef typename Func<T>::type Head; // apply to head
    typedef typename transform<U, Func>::type Tail; // tail is transformed tail

    typedef Typelist<Head, Tail> type; // put together
};

这适用于递归。它通过应用于头部,然后将其他所有内容作为尾部应用来创建一个新列表。这反过来会应用头部,依此类推,直到达到NullType,我们才会获得NullType

然后你只需要一个元函子:

template <typename T>
struct remove_const
{
    typedef T type;
};

template <typename T>
struct remove_const<const T>
{
    typedef T type;
};

然后把它们放在一起:

typedef TYPELIST_3(A, const B, B) TL;
typedef transform<TL, remove_const>::type TL2;
// TL2 is the same as TYPELIST_3(A, B, B)

应该注意我没有尝试过任何一种。