c++ - 了解模板的声明、定义和特化

标签 c++ c++11 templates variadic-templates template-specialization

我试图理解下面的例子,但我对三个不同的模板和结构声明有点困惑。

您能否描述一下下面的电话会发生什么?将使用哪些模板以及何时使用?

另外,为什么第一个模板+类声明在结构声明之后缺少“<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/

相关文章:

c++ - 从 C++ 调用 awk 脚本在 "bozo :wait_for"停止

c# - 如何在 C# 中创建未转义的十六进制字节字符串

c++ - 如何在 opengl Tessellation Evaluation 着色器中插入矩阵

c++ - 将 unique_ptr 传递给 strtok

c++ - 'const decltype((a))' 没有声明 const 引用?

c++ - 使用 srand 设置随机种子是现代 C++ 吗?

c# - 指针作为泛型 C#

java - 此代码出现运行时错误与编译错误的原因

c++ - libconfig++ : adding a setting to the root of the configuration tree

c++ - 为什么这个 CRTP 不能编译?