模板偏特化和默认模板参数的匹配顺序
程序员文章站
2022-03-09 19:53:20
...
在阅读Boost.ASIO的时候看到了下面这种写法:
template <typename CompletionToken, typename Signature = void>
class async_result
{
public:
//...
typedef CompletionToken completion_handler_type;
async_result<completion_handler_type> legacy_result_;
};
template <typename Handler>
class async_result<Handler>
{
//...
};
先开始没注意到下面这个偏特化版本,导致我始终不明白上面legacy_result_的成员声明那种写法,这看起来不是死循环了吗。但注意到偏特化模板类后又注意到一个问题,对于这种默认模板参数与偏特化都能匹配的时候,是实例化那种版本的模板类。(虽然从上面的写法中已经可以推理出答案了。。)
还是动手测试下:
先是在一个头文件中定义了2个模板类,模仿上面的情况。
template <class T, typename U = void>
class test {
public:
test() {
std::cout << "默认模板参数版本" << std::endl;
}
};
template <class T>
class test<T> {
public:
test() {
std::cout << "偏特化版本" << std::endl;
}
};
然后在main函数中创建一个test类型的局部变量:
int main() {
test<int> t;
}
输出
偏特化版本
看得出来优先匹配偏特化的版本。
接下来再做另一个测试,这次改为传入2个模板参数,不过2个模板类的定义也要稍微改下:
template <class T, typename U = void>
class test {
public:
test() {
std::cout << "默认模板参数版本" << std::endl;
}
};
template <class T>
class test<T, int> { // 注意这里多了一个模板参数
public:
test() {
std::cout << "偏特化版本" << std::endl;
}
};
这里只改了偏特化版本,使其具有2个模板参数。
此时main函数中再创建一个test变量:
int main() {
test<int, int> t;
test<int> t2;
}
输出
偏特化版本
默认模板参数版本
总结
在偏特化版本和模板参数版本都能匹配的情况下,优先匹配偏特化版本。
下一篇: 绘制动画及动画循环练习
推荐阅读