如何展开模板专业化

时间:2016-03-28 02:45:20

标签: c++ templates c++11 types variadic-templates

我试图使用模板元编程在参数包中的指定索引处获取类型。我有以下代码但由于某种原因它总是返回<ul> <li> <section class="a"> <img src="img.png" alt="Image"> <section class="b"> <p class="top-text">Text</p> <p class="bottom-text>More Text</p> </section> </section> </li> ... </ul>,有人可以告诉我我做错了什么吗?

int

上面的代码应该返回#include <string> #include <iostream> using std::cout; using std::endl; using std::string; template <int current_index, typename... Vs> struct TypeForIndex {}; template <int current_index, typename Head, typename... Tail> struct TypeForIndex<current_index, Head, Tail...> : private TypeForIndex<current_index + 1> { using type = Head; }; template <int current_index, typename Tail> struct TypeForIndex<current_index, Tail> { using type = Tail; }; int main() { TypeForIndex <2, int, double, string>::type a {"hello"}; cout << a << endl; return 0; } 作为string的类型,但不知何故它始终是a

2 个答案:

答案 0 :(得分:7)

TypeForIndex<2, int, double, string>

好的,模式匹配时间。首先,它明显匹配

template <int current_index, typename... Vs>
struct TypeForIndex {};

所以没有错误。它是否与其他专业相匹配?

A:

template <int current_index, typename Head, typename... Tail>
struct TypeForIndex<current_index, Head, Tail...>

B:

template <int current_index, typename Tail>
struct TypeForIndex<current_index, Tail>

嗯,它匹配(A)而不是(B)。

使用(A),current_index2HeadintTail...double, std::string

template <int current_index, typename Head, typename... Tail>
struct TypeForIndex<current_index, Head, Tail...> : private TypeForIndex<current_index + 1> {
    using type = Head;
};

现在,private TypeForIndex<current_index + 1>几乎没用。它总是只匹配主要特化,它具有一个空体,它是私有的,所以没有人会注意到它。我们可以删除它而不会改变程序的行为。

template <int current_index, typename Head, typename... Tail>
struct TypeForIndex<current_index, Head, Tail...> {
    using type = Head;
};

如上所述,Headint。我们得到type=int

就是这样。这就是为什么typeint

...

你做错了什么几乎是一切?除了编译(即,存在与签名匹配的主要专业化)之外,您提供的代码与您在文本中描述的内容无关。即使current_index+1是一个我不希望存在于代码中的字符串,它可以执行文本描述的内容。

抛弃除主要专业化以外的所有内容,这有效:

template <typename Head, typename... Tail>
struct TypeForIndex<0, Head, Tail...> {
  using type = Head;
};
template <int current_index, typename Head, typename... Tail>
struct TypeForIndex<current_index, Head, Tail...>:
  TypeForIndex<current_index-1, Tail...>
{};

如果传递过大的索引,它就会正确地缺少type的定义。

我还会使用size_t而不是int

答案 1 :(得分:2)

这是你的修复。

#include <string>
#include <iostream>
using std::cout;
using std::endl;
using std::string;

template <int current_index, typename... Vs>
struct TypeForIndex {};

template <int current_index, typename Head, typename... Tail>
struct TypeForIndex<current_index, Head, Tail...> : TypeForIndex<current_index - 1, Tail...> {};

template <typename Head, typename... Tail>
struct TypeForIndex<0, Head, Tail...> {
    using type = Head;
};

int main() {
    TypeForIndex <2, int, double, string, char>::type a ("hello");
    cout << a << endl;
}