std::function 在 C++17 中使用 noexcept

std::function with noexcept in C++17

在 C++17 中 noexcept has 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<void() noexcept>.

的奇怪错误

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

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

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

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

因为 void() noexcept 不匹配偏特化,所以 std::function<void() noexcept> 是一个不完整的类型。 Clang 和 GCC trunk 都相应地对此进行了诊断。