如何展开模板专业化
How to unroll template specializations
我正在尝试使用模板元编程来获取参数包中指定索引处的类型。我有下面的代码,但由于某种原因,它总是返回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
的类型,但不知何故,它始终是int
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_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...>
{};
如果传递过大的索引,则它适当地缺少CCD_ 18的定义。
我也会使用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;
}
相关文章:
- 如何使用默认参数等选择模板专业化
- 模板化建造师专业化
- 函数何时会在c++中包含stack_Unwind_Resume调用
- 类模板的成员功能的定义在单独的TU中完全专业化
- 将结构字段的类型展开为可变模板参数
- Python中的for循环与C++有何不同
- 循环展开 - G++ 与 Clang++
- 部分专业化和嵌套模板
- 模板专业化可以进入我的.cpp吗?
- 为什么我的共享库中存在展开符号
- 别名模板的专业化 C++11 中没有开销的最佳替代方案
- 部分专业化和对标准::void_t<>的需求
- 在C++中释放内存期间,迭代器与指针有何不同
- 展开可变参数模板结构
- "专业化不参与超载"
- 特定好友功能专业化
- 是否可以混合使用SFINAE和模板专业化?
- 标准对此指向成员函数类型模板参数有何说明?是我的代码有误,还是 MSVS 16.6 有问题?
- 如何编写将展开以定义具有模板参数的对象的宏
- 如何展开模板专业化