Как `std :: mem_fn` обнаруживает отсутствие исключений в gcc 7.1.0

С gcc 7.1.0 std::mem_fn может обнаружить noexcept-ness по указателю на функцию-член. Как оно работает? Я думал noexcept спецификатор не был частью типа функции?


Что еще более запутанно, так это когда я удаляю спецификатор noexcept для одного метода из https://wandbox.org/permlink/JUI3rsLjKRoPArAl все значения noexcept изменяются, как показано здесь https://wandbox.org/permlink/yBJ0R4PxzAXg09ef. И когда кто-то не исключает, все не исключают. Как? Это ошибка?

3

Решение

Поведение, которое вы видите с 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 (поэтому обновите ваш компилятор).

6

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]