基本类型列表功能

时间:2011-10-09 15:36:36

标签: c++ typelist

我在使用TypeLists或模板列表时遇到了一些麻烦。那就是:

class nulltype{};

template <typename HEAD, typename TAIL>
struct tlist
{
    typedef HEAD head;
    typedef TAIL tail;
}; 

template <class TList>
class OutputClass
{
public:
    void output(Type t) 
    {
        std::cout << t << endl;
    }
};

typedef tlist<double,tlist<float,NullType> > floatingPoints;    
typedef tlist<std::string,tlist<char *,NullType> > text;   

int main()
{
    OutputClass<floatingPoints> floats = OutputClass<floatingPoints>();
    floats.output(1.0f);

    OutputClass<text> strings = OutputClass<text>();
    floats.output("hello");
    return 0;
}

基本上我的目标是我希望OutputClass.output输出传递给它的参数,但前提是该类实例typelist包含传递给函数的类型。即。参考上面的代码:浮点数只能输出其类型列表“floatingPoints”定义的float类型和double类型。如果传入一个字符串或int,我希望它会出错。

我有一段时间试图找到有关如何执行此操作的任何示例,我已经找到了一百万次的索引示例和长度示例,并且他们帮助了我很多,但我只是可以似乎没想到最后一点了。任何和所有帮助将不胜感激。

1 个答案:

答案 0 :(得分:3)

我们首先需要一些辅助模板。第一个检查两种类型是否相同:

template <typename T, typename U>
struct is_same
{
    // Default case: T and U are not the same type
    static const bool value = false;
};

template <typename T>
struct is_same<T, T>
{
    // Specialization: both template arguments are of the same type
    static const bool value = true;
};

我们现在可以使用布尔值is_same<T, U>::value来确定类型TU是否相同。

使用is_same我们现在可以编写一个模板来检查类型列表中是否出现特定类型:

template <typename TList, typename T>
struct contains
{
    static const bool value =
         is_same<typename TList::head, T>::value   // Base case
      || contains<typename TList::tail, T>::value; // Recursion
};

template <typename T>
struct contains<nulltype, T>
{
    // Termination condition
    static const bool value = false;
};

这是一个递归模板,使用nulltype上的特化来终止递归。

我们需要的最后一个帮助模板是enable_if

template <bool Cond, typename T=void>
struct enable_if
{
    // Default case: Cond assumed to be false, no typedef
};

template <typename T>
struct enable_if<true, T>
{
    // Specialization: Cond is true, so typedef
    typedef T type;
};

enable_if<true, T>::type产生T,而enable_if<false, T>::type未定义。我们利用SFINAE规则启用或禁用函数,具体取决于其模板参数,如下所示:

template <typename TList>
class OutputClass
{
public:
    // Only enable the function if T is in TList (by SFINAE)
    template <typename T>
    typename enable_if<contains<TList, T>::value>::type
    output(T t) 
    {
        std::cout << t << std::endl;
    }
};

相当一次旅行,但如果您了解所有这些,那么您就可以掌握模板元编程。有关模板元编程的深入讨论,我建议您选取C++ Template Metaprogramming(ISBN-13:9780321227256)的副本。