【问题标题】:Basic Typelist functionality基本类型列表功能
【发布时间】:2011-12-04 00:16:52
【问题描述】:

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

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 包含传递给函数的类型。 IE。参考上面的代码:floats只能输出其类型列表“floatingPoints”定义的float类型和double类型。如果传入一个字符串或整数,我希望它会出错。

我正在努力寻找任何关于如何做到这一点的示例,我已经找到了一百万次的索引示例和长度示例,它们对我帮助很大,但我可以似乎没有弄清楚这最后一点。我们将不胜感激。

【问题讨论】:

  • 啊,别管我的回答,我完全误读了这个问题。
  • 没问题,感谢您的光临和破解 :) 非常感谢。

标签: c++ typelist


【解决方案1】:

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

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&lt;T, U&gt;::value 来确定@​​987654325@ 和U 类型是否等价。

使用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&lt;true, T&gt;::type 产生T,而enable_if&lt;false, T&gt;::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)的副本。

【讨论】:

  • 就像一个魅力。我发现这些类型列表真的很吸引人,我一定要看看那本书。再次感谢!你现在真的帮助我更好地理解类型列表
  • 如果一个函数模板的标准格式是template &lt;typename T&gt; [return type] [name]([arguments]),那么这是否意味着OutputClass::output()的返回类型是实例化模板typename enable_if&lt;contains&lt;TList, T&gt;::value&gt;::type的结果?
  • @Chris enable_if&lt;contains&lt;TList, T&gt;::value&gt;::type 在技术上不是模板,它是恰好在模板中定义的typedef。但是是的,它是OutputClass&lt;TList&gt;::output&lt;T&gt;() 的返回类型。这回答了你的问题吗?
  • 该书的链接截至 2016.04.18 已失效
  • @ofloveandhate 谢谢,我更新了链接并添加了 ISBN 以供将来参考。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-07
  • 1970-01-01
  • 2016-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多