【发布时间】:2021-09-08 14:35:06
【问题描述】:
在以下程序中,我尝试使用类型的元结构迭代类型列表。
除非我在基本打印模板定义之前指定template<>,否则它可以编译并正常工作。
/* example.cpp */
#include <iostream>
template<typename ...>
struct List{};
template<typename T,typename ...Rest>
void print(List<T,Rest ...> *) {
std::cout << typeid(T).name() << std::endl;
print((List<Rest ...> *)nullptr);
}
// uncommenting the next line creates compilation error
// template<>
void print(List<> *) {
}
int main() {
using L = List<int,double,float>;
print((L*)nullptr);
}
/* compile and execution
g++ (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
g++ -std=c++11 example.cpp
./a.out
i
d
f
*/
如果我在 void print(List<> *) 定义之前取消注释 template<>,g++ 和 clang++ 都会显示错误。
// clang++ error
error.cpp:15:6: error: no function template matches function template specialization 'print'
void print(List<> *) {
^
error.cpp:8:6: note: candidate template ignored: failed template argument deduction
void print(List<T,Rest ...> *) {
^
1 error generated.
我不明白为什么这种形式的完全专业化不适用于template<> 作为模板标题?我在这里缺少一些函数模板规则吗?
谢谢!
更新:
当我添加了一个额外的强制模板参数U时,以下程序编译并运行良好。
#include <iostream>
template<typename ...>
struct List{};
template<typename U,typename T,typename ...Rest>
void print(U* , List<T,Rest ...> *) {
std::cout << typeid(T).name() << std::endl;
print((int*)nullptr, (List<Rest ...> *)nullptr);
}
// I dont understand, that `T` is missing here, but still compiles
template<typename U>
void print(U *,List<> *) {
}
int main() {
using L = List<int,double,float>;
print((int*)nullptr,(L*)nullptr);
}
我不明白第一个程序中the error的原因和第二个程序中no error的原因。
【问题讨论】:
-
模板函数专业化是一个蠕虫罐头。重载它们只是更容易推理。