SFINAE 在使用异常时仍然产生错误
SFINAE still produces error while using exception
我正在学习 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
,但事实并非如此。谁能解释一下背后的原因。
问题是异常规范不参与模板参数推导(TAD).这在下面更详细地解释。 Source: C++ Templates: The Complete Guide Page No. 290
案例一
这里我们考虑示例1。在这种情况下,由于没有func
函数模板声明中的错误timer
triggers模板参数推导失败又名 SFINAE,通过选择普通函数 timer
允许调用 timer(5);
成功,您将获得预期的输出。
案例二
这里我们考虑示例 2。在这种情况下,因为异常规范不参与 TAD,重载解析 选择函数模板版本,因此当异常规范实例化时稍后,程序变为 ill-formed 并且您会收到上述错误。
换句话说,异常规范仅在需要时实例化,就像默认调用参数。
我正在学习 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
,但事实并非如此。谁能解释一下背后的原因。
问题是异常规范不参与模板参数推导(TAD).这在下面更详细地解释。 Source: C++ Templates: The Complete Guide Page No. 290
案例一
这里我们考虑示例1。在这种情况下,由于没有func
函数模板声明中的错误timer
triggers模板参数推导失败又名 SFINAE,通过选择普通函数 timer
允许调用 timer(5);
成功,您将获得预期的输出。
案例二
这里我们考虑示例 2。在这种情况下,因为异常规范不参与 TAD,重载解析 选择函数模板版本,因此当异常规范实例化时稍后,程序变为 ill-formed 并且您会收到上述错误。
换句话说,异常规范仅在需要时实例化,就像默认调用参数。