Стоит отметить, что в кругах власти было интересное обсуждение проблем, не связанных с норой.Я настоятельно рекомендую прочитать эти:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3227.html
http://www.stroustrup.com/N3202-noexcept.pdf
По-видимому, весьма влиятельные люди заинтересованы в добавлении какой-то автоматической nothrow дедукции C++.
После некоторого раздумья я изменил свою позицию почти напротив, смотри ниже
Рассмотрим это:
при вызове функции, имеющей noexcept
на декларацию - вы извлечь выгоду из этого (не нужно иметь дело с возможностью разворота и т. д.)
, когда компилятор компилирует функцию, которая имеет noexcept
по адресу Определить - (если компилятор не может доказать, что функция действительно не очень важна) производительность (теперь компилятор должен гарантировать, что исключение не сможет избежать этой функции). Вы просите его выполнить обещания без исключений
I.e. noexcept
оба причиняют вам боль и приносят пользу. Это не так, если функция встроена! Когда он встроен - нет никакой пользы от noexcept от объявления вообще (декларация и определение становятся одной вещью). То есть, если вы на самом деле не хотите, чтобы компилятор обеспечивал это ради безопасности. А по безопасности Я имею в виду , вы скорее закончите, чем произведете неправильный результат.
Это должно быть очевидно, сейчас - нет никакого смысла объявляя встраиваемыми функции noexcept
(имейте в виду, что не каждый рядный функция собирается получить встраиваемыми).
Давайте посмотрим на различные категории функций, которые не бросают (вы просто знаете, что они не делают):
без встраиваемыми, компилятор может доказать, что он не бросает - noexcept
(компилятор просто проигнорирует спецификацию), а сайты-вызовы выиграют от этого обещания.
не-встроенный, компилятор не может доказать, что он не выбрасывает - noexcept
может повредить функциональный орган, но преимущество (трудно сказать, что более выгодно)
встраиваемого, компилятор может доказать, что он не бросает - noexcept
не служит никакой цели
встраиваемой, компилятор не может доказать, что он не бросает - noexcept
повредит сайт вызова
Как видите, nothrow
- это просто плохо разработанная языковая функция. Он работает только в том случае, если вы хотите выполнить обещание без исключений. Невозможно использовать его - он может дать вам «безопасность», но не производительность.
noexcept
ключевое слово в конечном итоге используется как в качестве обещания (по объявлению), так и в отношении принудительного исполнения (по определению) - не идеальный подход, я думаю (lol, второй удар по спецификациям исключения и мы все равно не поняли его) ,
Итак, что делать?
объявить свое поведение (увы, язык не имеет ничего, чтобы помочь вам здесь)! Например:
void push_back(int k); // throws only if there is no unused memory
не ставят noexcept
на встроенных функций (если это не вряд ли будет встраиваемыми, например, очень большой)
для не встроенных функций (или функция, которая вряд ли быть встроенным) - позвонить. Чем больше функция получает, тем меньше noexcept
"отрицательный эффект S становится (сравнительно) - в какой-то момент он, вероятно, имеет смысл указать его для вызывающих абонентов выгоды
использования noexcept
на ходу конструктора и перемещения оператора присваивания (и деструктор?). Это может повлиять на них отрицательно, но если вы этого не сделаете - некоторые функции библиотеки (std :: swap, некоторые операции с контейнерами) не будут использовать наиболее эффективный путь (или не будут предоставлять лучшую гарантию исключения). В принципе, любое место, которое использует noexcept
Оператор на вашей функции (на данный момент) заставит вас использовать noexcept
спецификатор.
использование noexcept
если вы не доверяете вызывает ваша функция делает и скорее умру, чем он себя неожиданно
чистые виртуальные функции - чаще всего вы не доверяете людям, реализующие эти интерфейсы. Часто это делает страхование смысл покупки (указав noexcept
)
Ну, как еще noexcept
могут быть разработаны?
Я хотел бы использовать два различные ключевые слова - один для объявления обещания, а другое для обеспечения соблюдения его. Например. noexcept и force_noexcept. Фактически, принудительное выполнение на самом деле не требуется - это может быть сделано с помощью try/catch + terminate() (да, он разматывает стек, но кто волнуется, если за ним следует std :: terminate()?)
Я бы заставил компилятор проанализировать все вызовы в заданной функции, чтобы определить, может ли она быть выбрана. Если это так, и было сделано безусловное обещание - ошибка компилятора будет испускаться
Код, который может быть брошен, но вы знаете, что этого не должно быть, чтобы обеспечить компилятор, чтобы он был в порядке. Smth так:
vector<int> v;
v.reserve(1);
...
nothrow { // memory pre-allocated, this won't throw
v.push_back(10);
}
если обещание нарушается (то есть кто-то изменил вектор кода и теперь предоставляет другие гарантии) - неопределенное поведение.
Отказ от ответственности: этот подход может быть слишком непрактично, кто знает ...
'try'-блок подразумевает стек разматывания. Вызов 'terminate' не делает. – dyp
Эффективность в стороне, это может быть ситуационно полезным, если функция действительно должна быть небезопасной. – templatetypedef
@dyp: Когда я написал «эквивалент блока« try », я пытался выразить мысль о том, что код все равно должен быть сгенерирован для обнаружения исключений во время выполнения и для вызова« прекратить », если они возникнут. Я согласен с тем, что сгенерированный код не должен делать именно то, что бы сделал настоящий блок try. – KnowItAllWannabe