Std:: function с noexcept в С++ 17

В С++ 17 noexcept добавлен в систему типов:

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

int main()
{
    r1(foo);
}

Последние версии gcc и clang в режиме С++ 17 отклоняют вызов 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>.

Какое правильное поведение для этой второй программы в С++ 17?

Ответы

Ответ 1

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 диагностируют это соответственно.