Я написал следующий код для тестирования noexcept
распространение через вызовы функций, и кажется, что это не работает, как я бы подумал. В GCC 4.7.2 функция может быть эффективно протестирована на noexcept
только напрямую или при передаче в качестве аргумента специализации шаблона; но не при передаче в качестве аргумента шаблонной функции или в качестве указателя на нормальную функцию, даже если эта функция объявляет свой формальный параметр как noexcept
, Вот код:
#include <iostream>
#define test(f) \
std::cout << __func__ << ": " #f " is " \
<< (noexcept(f()) ? "" : "not ") \
<< "noexcept\n";
template <void(*f)()>
static inline void test0() {
test(f);
}
template <typename F>
static inline void test1(F f) {
test(f);
}
static inline void test2(void(*f)()) {
test(f);
}
static inline void test3(void(*f)()noexcept) {
test(f);
}
void f1() {}
void f2() noexcept {}
int main() {
test(f1);
test(f2);
test0<f1>();
test0<f2>();
test1(f1);
test1(f2);
test2(f1);
test2(f2);
test3(f1);
test3(f2);
return 0;
}
И вот вывод:
главное: f1 не исключение main: f2 - это не исключение test0: f не исключение test0: f не исключение test1: f не исключение test1: f не исключение test2: f не исключение test2: f не исключение test3: f не исключение test3: f не исключение
Почему noexcept
Несс не распространяется в других случаях? В случае test1
вся функция «создается» с правильным типом F
в это время компилятор наверняка знает, является ли F noexcept
функция. Почему можно написать test3
как я это написал, когда noexcept
Несс декларация полностью игнорируется?
Стандарт должен сказать что-то конкретное по этому поводу?
В C ++ 17 noexcept
наконец добавляется в систему типов. Указатель на неnoexcept
функция не может быть неявно преобразована в указатель на noexcept
функция. (Но наоборот разрешено).
лязг 3.9.0 с -std=c++1z
и g ++ 7.0 с -std=c++17
отклонить строку test3(f1);
,
В разделе 15.4.13 стандарта C ++ 11 говорится, что «спецификация исключений не считается частью типа функции».