在模板中使用noexcept运算符

时间:2019-10-16 07:17:45

标签: c++ visual-studio-2017 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专业版15.6.3开发的。

感谢阅读。

奥利维尔

1 个答案:

答案 0 :(得分:2)

如果表达式noexcept(X)为noexcept,则

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

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