【问题标题】:Use of noexcept operator in template在模板中使用 noexcept 运算符
【发布时间】:2019-10-16 15:23:05
【问题描述】:

我试图更多地了解 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-2017 noexcept


    【解决方案1】:

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

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

    【讨论】:

    • 感谢您的回答。因此,如果我理解正确,在我给出的示例中,noexcept 测试构造、函数调用和销毁。并且使用 declval 仅测试函数调用中的 noexcept 值?
    • @Olivier:正确。除非另有说明,否则析构函数默认为 noexcept。我给的解决方案测试了declval和Test方法调用,还好declval是noexcept。
    • 很高兴知道它还测试 declval 并且它是 noexcept。
    猜你喜欢
    • 2015-10-17
    • 1970-01-01
    • 2022-12-08
    • 1970-01-01
    • 2017-05-03
    • 1970-01-01
    • 2011-07-02
    • 2012-06-17
    • 2018-08-03
    相关资源
    最近更新 更多