我试图理解下面的例子,但我对三个不同的模板和结构声明有点困惑。
您能否描述一下下面的电话会发生什么?将使用哪些模板以及何时使用?
另外,为什么第一个模板+类声明在结构声明之后缺少“<S...>
”?(查看注释掉的内容)?什么时候添加合适,什么时候不合适?
#include <iostream>
#include <stdio.h>
using namespace std;
template<typename... S>
struct Example /* <S...> */ ;
template<typename H, typename... T>
struct Example<H, T...>
{
static const size_t value = sizeof(H) + Example<T...>::value;
};
template<>
struct Example<>
{
static const size_t value = 0;
};
int main(){
cout << Example<long, int, char>::value << endl;
return 0;
}
输出:13
最佳答案
第一个声明了 struct
的模板命名为 Example
,接受任意数量的类型:
template<typename... S>
struct Example /* <S...> */ ;
如果新声明的模板名称后跟<>
,无论有无参数,它都将是一个特化!
第二个定义了至少一个类型参数的部分特化:
template<typename H, typename... T>
struct Example<H, T...>
{
static const size_t value = sizeof(H) + Example<T...>::value;
};
最后一个定义了一个没有类型参数的完整特化:
template<>
struct Example<>
{
static const size_t value = 0;
};
请注意 template
后面是空的<>
-括号。
在完全特化之前定义部分特化并不重要,因为实例化必须推迟到模板类型参数已知为止。
您使用的具体实例,Example<long,int,char>::value
, 取决于 Example<int, char>::value
, 这取决于 Example<char>
,这导致了基本情况:
Example<long, int, char>::value = sizeof(long) + Example<int, char>::value; // sizeof(long) + sizeof(int) + 1 + 0
Example<int, char>::value = sizeof(int) + Example<char>::value; // sizeof(int) + 1 + 0
Example<char>::value = sizeof(char) + Example<>::value; // 1 + 0
Example<>::value = 0;
当然,这个例子可以简化:
template <class... T>
struct Example {
static const size_t value = 0;
static_assert(!sizeof...(T), "The base-template only handles no template arguments.");
};
template <class H, class... T>
struct Example {
static const size_t value = sizeof(H) + Example<T...>::example;
};
或者使用 C++17 折叠表达式:
template <class... T>
struct Example {
static const size_t value = 0 + ... + sizeof(T);
};
顺便说一句,有充分的理由永远不要使用 using namespace std;
,不知道为什么你#include <stdio.h>
, 和 return 0;
main()
是多余的.
关于c++ - 了解模板的声明、定义和特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55109599/