【问题标题】:std::function with noexcept in C++17在 C++17 中使用 noexcept 的 std::function
【发布时间】:2017-05-08 15:53:55
【问题描述】:

在 C++17 中noexcepthas been added to the type system

void r1( void (*f)() noexcept ) { f(); }
void foo() { throw 1; }

int main()
{
    r1(foo);
}

最新版本的C++17模式的GCC和Clang拒绝调用r1(foo),因为void (*)()不能隐式转换为void (*)() noexcept

但是用std::function 代替:

#include <functional>

void r2( std::function<void() noexcept> f ) { f(); }
void foo() { throw 1; }

int main()
{
    r2(foo);
}

Clang 接受程序,显然忽略了noexcept 说明符; g++ 给出了一个关于 std::function&lt;void() noexcept&gt; 的奇怪错误。

C++17 中第二个程序的正确行为是什么?

【问题讨论】:

  • 如果noexcept 现在被认为是类型的一部分,那么void () noexceptvoid () 不同,因此这是格式错误的。与 Java 不同,不包括异常规范作为函数签名的一部分是我一直认为 C++ 出错的地方。很高兴看到这个问题正在得到纠正。
  • 行为是它应该抱怨一个不完整的类型。 std::function 部分专用于 R(Args...),而不是 R(Args...) noexcept
  • @T.C.好的,那么 g++ 7 的正确行为。你能把评论写成答案吗?
  • 即使在 C++14 中,您的第一个 sn-p 也是无效的:timsong-cpp.github.io/cppwp/n4140/except.spec#5

标签: c++ function c++17 noexcept


【解决方案1】:

std::function的定义在当前工作草案中没有改变:

template<class T>
class function; // not defined

template<class R, class... ArgTypes>
class function<R(ArgTypes...)> {
    /* ... */
};

由于void() noexcept 不匹配部分特化,std::function&lt;void() noexcept&gt; 是一个不完整的类型。 Clang 和 GCC 主干都会相应地对此进行诊断。

【讨论】:

  • 据我所知,std::function 尚未更新为在 C++17 中包含对 R(ArgTypes...) noexcept 的部分特化,甚至还没有引入 C++20。这是标准委员会曾经解决过的问题吗(公众对此事的了解)? MSVC++、GCC 和 Clang 在使用 target 时都强制使用 noexcept 签名(如果存在),但您不能将其用作类模板签名的一部分。对我来说,这似乎违反了 noexcept 作为函数签名一部分的整个概念。感谢您对此的任何更新/反馈。
猜你喜欢
  • 2018-10-29
  • 2015-10-14
  • 2017-04-04
  • 1970-01-01
  • 2018-03-22
  • 2016-01-09
  • 1970-01-01
  • 2019-05-21
  • 2021-10-26
相关资源
最近更新 更多