如何展开模板专业化
How to unroll template specializations
我正在尝试使用模板元编程获取参数包中指定索引处的类型。我有下面的代码,但由于某种原因,它总是 return 一个 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;
}
上面的代码应该 return string
作为 a
的类型,但不知何故它总是 int
TypeForIndex<2, int, double, string>
好的,模式匹配时间到了。首先,它显然符合
template <int current_index, typename... Vs>
struct TypeForIndex {};
所以没有错误。它是否与任何其他专业匹配?
甲:
template <int current_index, typename Head, typename... Tail>
struct TypeForIndex<current_index, Head, Tail...>
乙:
template <int current_index, typename Tail>
struct TypeForIndex<current_index, Tail>
嗯,它匹配 (A) 而不是 (B)。
对于 (A),current_index
是 2
,Head
是 int
,Tail...
是 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;
};
如上所述,Head
是 int
。所以我们得到 type=int
.
就是这样。这就是为什么 type
是 int
.
...
你做错的几乎是一切?除了编译(即存在与签名匹配的主要专业化)之外,您提供的代码与您在文本中描述的内容无关。即使 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
。
这是您的解决方法。
#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;
}
我正在尝试使用模板元编程获取参数包中指定索引处的类型。我有下面的代码,但由于某种原因,它总是 return 一个 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;
}
上面的代码应该 return string
作为 a
的类型,但不知何故它总是 int
TypeForIndex<2, int, double, string>
好的,模式匹配时间到了。首先,它显然符合
template <int current_index, typename... Vs>
struct TypeForIndex {};
所以没有错误。它是否与任何其他专业匹配?
甲:
template <int current_index, typename Head, typename... Tail>
struct TypeForIndex<current_index, Head, Tail...>
乙:
template <int current_index, typename Tail>
struct TypeForIndex<current_index, Tail>
嗯,它匹配 (A) 而不是 (B)。
对于 (A),current_index
是 2
,Head
是 int
,Tail...
是 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;
};
如上所述,Head
是 int
。所以我们得到 type=int
.
就是这样。这就是为什么 type
是 int
.
...
你做错的几乎是一切?除了编译(即存在与签名匹配的主要专业化)之外,您提供的代码与您在文本中描述的内容无关。即使 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
。
这是您的解决方法。
#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;
}