首页 > 解决方案 > 在模板中使用 noexcept 运算符

问题描述

我试图更多地了解 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 下开发的。

谢谢阅读。

奥利维尔

标签: c++visual-studio-2017noexcept

解决方案


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

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


推荐阅读