我正在学习 C++ 中的 SFINAE。因此,在阅读完相关内容后,我正在尝试不同的示例以更好地理解这个概念。下面我给出了 2 个片段,其中 1 个我能理解,但第二个片段是我使用过的noexcept
在声明中我无法理解。
实施例1: 这个我能理解。
#include <iostream>
template<typename T>
decltype(func(T())) timer(T a)
{
std::cout<<"template timer called"<<std::endl;
return func(T());
}
void timer(...)
{
std::cout<<"ordinary timer called"<<std::endl;
}
int main()
{
timer(5);
return 0;
}
上述程序的输出(如预期)是:
ordinary timer called
我可以理解,由于SFINAE,扣除会导致失败,所以普通timer
将被调用。
实施例2: 为什么在这个例子中会出现错误。
#include <iostream>
template<typename T>
void timer(T a) noexcept(func(T()))
{
std::cout<<"template timer called"<<std::endl;
}
void timer(...)
{
std::cout<<"ordinary timer called"<<std::endl;
}
int main()
{
timer(5);
return 0;
}
第二个示例会导致错误:func
没有宣布。我的问题是为什么就像示例1一样这里也由于推论失败而普通timer
没有被选中?
我以为这里也很普通timer
应该被调用,但事实并非如此。有人可以解释其背后的原因吗?
The problem就是它异常规范不参加模板参数推导(TAD)。下面对此进行更详细的解释。来源:C++ 模板:完整指南第 290 页 https://www.amazon.in/Templates-Complete-Guide-David-Vandevoorde/dp/0321714121
Case 1
这里我们考虑示例 1。在这种情况下,由于没有func
函数模板声明错误timer
triggers模板参数推导失败又名 SFINAE 允许调用timer(5);
选择普通功能即可成功timer
然后你就得到了预期的输出。
Case 2
这里我们考虑示例 2。在这种情况下,因为异常规范不参与 TAD,过载解析选择函数模板版本,因此当稍后实例化异常规范时,程序变为不规范的并且您收到上述错误。
换句话说,异常规范仅在需要时才实例化,就像默认调用参数.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)