С gcc 7.1.0 std::mem_fn
может обнаружить noexcept-ness по указателю на функцию-член. Как оно работает? Я думал noexcept
спецификатор не был частью типа функции?
Что еще более запутанно, так это когда я удаляю спецификатор noexcept для одного метода из https://wandbox.org/permlink/JUI3rsLjKRoPArAl все значения noexcept изменяются, как показано здесь https://wandbox.org/permlink/yBJ0R4PxzAXg09ef. И когда кто-то не исключает, все не исключают. Как? Это ошибка?
Поведение, которое вы видите с GCC в режиме C ++ 14, является ошибкой, смотрите https://gcc.gnu.org/PR77369
В комментариях вы спрашиваете:
Кроме того, объявление mem_fn, поскольку c ++ 17 не имеет перегрузки noexcept, тогда как он обнаруживает эту информацию от пользователя?
Это не должно иметь перегрузку noexcept, рассмотрите этот код C ++ 17:
template<typename T>
constexpr bool is_noexcept_callable(T t) {
return noexcept(t());
}
void f() noexcept { }
void g() { }
static_assert( is_noexcept_callable(f) );
static_assert( !is_noexcept_callable(g) );
Там нет необходимости иметь исключение перегрузки is_noexcept_callable
потому что в C ++ 17 спецификация исключений является частью типа, поэтому вся информация уже закодирована в типе T
, Когда вы создаете экземпляр std::mem_fn
с указателем на noexcept(true)
Функция знает, что вызов этой функции не может сгенерировать. Когда вы создаете его с noexcept(false)
Функция знает, что может бросить.
Наконец, причина, по которой ваш пример не компилируется в режиме C ++ 17 с GCC 7.1, заключается в том, что https://gcc.gnu.org/PR80478 что исправлено в GCC 7.2 (поэтому обновите ваш компилятор).
Других решений пока нет …