在模板中使用 noexcept 运算符

Use of noexcept operator in template

本文关键字:noexcept 运算符      更新时间:2023-10-16

我试图更多地了解noexcept 运算符的工作原理以及如何在模板中使用它。 我的目标是启用或禁用模板函数,具体取决于成员函数类之一的 noexcept 类型。

class ObjTestNoExcept
{
public:
ObjTestNoExcept() noexcept {}
void Test() noexcept {}
};
class ObjTestExcept
{
public:
ObjTestExcept() {}
void Test() {}
};
template <class T, typename = typename std::enable_if_t<noexcept(T().Test()), T>>
void DoSomething()
{
std::cout << "OK" << std::endl;
}
int main()
{
DoSomething<ObjTestNoExcept>();
DoSomething<ObjTestExcept>(); // error C2672: 'DoSomething': no matching overloaded function found
return 0;
}

它按预期工作 ObjTextExcept 类并禁用函数,它按预期工作 ObjTestNoExcept 类并启用函数。

但是,如果我删除 ObjTestNoExcept 类上的 noexcept 关键字,则该函数将被禁用,而它仍然是 noexcept。

class ObjTestNoExcept
{
public:
ObjTestNoExcept() {}
void Test() noexcept {}
};
template <class T, typename = typename std::enable_if_t<noexcept(T().Test()), T>>
void DoSomething()
{
std::cout << "OK" << std::endl;
}
int main()
{
DoSomething<ObjTestNoExcept>(); // error C2672: 'DoSomething': no matching overloaded function found
return 0;
}

我无法弄清楚删除构造函数上的 noexcept 关键字有什么问题。

此代码是在Visual Studio 2017 Professional Version 15.6.3下开发的。

感谢您的阅读。

奥利维尔

如果表达式X为noexcept,则noexcept(X)为真。在第二个例子(noexcept(T().Test())(中,混合了两件事:T的构造,然后调用Test方法。这就是为什么从构造函数中删除 noexcept 会破坏代码的原因。

若要避免假定默认构造函数为 noexcept ,请使用:noexcept(std::declval<T>().Test())