R>Покажите интересные нетривиальные примеры expr, которые можно использовать на практике.
Вот например, есть шаблонный метод:
template <typename T>
void foo(const T &a1, const T &a2) noexcept(expr)
{
...
if ((a1 == a2) || (a1 > a2))
...
}
После анализа, я делаю вывод что если и могут быть исключения, то только внутри указанной строки кода, причем T может быть также и тривиальным типом. Как это должно быть отражено в noexcept(expr)?
Спасибо за пример.
Я просто о том что конструкцию типа Meta::HasNothrowDefaultCtor<I> я не смогу использовать на практике, ну мало ли что там внутри. Хочется конкретики.
Здравствуйте, Ruzzz, Вы писали:
R>Вот например, есть шаблонный метод: R>
template <typename T>
R>void foo(const T &a1, const T &a2) noexcept(expr)
R>{
R> ...
R> if ((a1 == a2) || (a1 > a2))
R> ...
R>}
R>
R>После анализа, я делаю вывод что если и могут быть исключения, то только внутри указанной строки кода, причем T может быть также и тривиальным типом. Как это должно быть отражено в noexcept(expr)?
В этом случае необходимо использовать std::declval:
См. пример кода, который успешно компилируется с помощью g++ 6.3.0 и clang++ 3.8.0 при заданных ключах компиляции -std=c++11 -Wall -Wextra -Werror -pedantic-errors.
Constructor:
C>Здравствуйте, Ruzzz, Вы писали:
R>>Вот например, есть шаблонный метод: R>>
template <typename T>
R>>void foo(const T &a1, const T &a2) noexcept(expr)
R>>{
R>> ...
R>> if ((a1 == a2) || (a1 > a2))
R>> ...
R>>}
R>>
R>>После анализа, я делаю вывод что если и могут быть исключения, то только внутри указанной строки кода, причем T может быть также и тривиальным типом. Как это должно быть отражено в noexcept(expr)?
C>В этом случае необходимо использовать std::declval:
Необходимости использовать declval там нет, т.к. в noexcept-specification можно использовать имена параметров функции (так же, как и в trailing-return-type)
Здравствуйте, N. I., Вы писали:
NI>Необходимости использовать declval там нет, т.к. в noexcept-specification можно использовать имена параметров функции (так же, как и в trailing-return-type)
template <typename T>
void foo(const T& a1, const T& a2) noexcept(auto)
{
// ...if (a1 == a2 || a1 > a2)
// ...
[[noexcept]]
{
// а здесь мы что-то вызвали, что не бросает, но компилятор не знает об этом
}
}
Здравствуйте, N. I., Вы писали:
NI>Необходимости использовать declval там нет, т.к. в noexcept-specification можно использовать имена параметров функции (так же, как и в trailing-return-type)
NI>
В общем случае в подозрительной строке/строках могут фигурировать отнюдь не только параметры функции, а какие-нибудь локальные переменные (тип которых может находиться в некой взаимосвязи с параметром шаблона). И тогда std::declval может понадобиться.
Alexander:
AG>Всё равно не хочу такую колбасу писать, хочу так AG>
AG>template <typename T>
AG>void foo(const T& a1, const T& a2) noexcept(auto)
AG>{
AG> // ...
AG> if (a1 == a2 || a1 > a2)
AG> // ...
AG> [[noexcept]]
AG> {
AG> // а здесь мы что-то вызвали, что не бросает, но компилятор не знает об этом
AG> }
AG>}
AG>
Так смогут писать твои внуки, когда соответствующий proposal допилят и включат в стандарт.
Здравствуйте, Alexander G, Вы писали:
AG>Всё равно не хочу такую колбасу писать, хочу так AG>
AG>template <typename T>
AG>void foo(const T& a1, const T& a2) noexcept(auto)
AG>{
AG> // ...
AG> if (a1 == a2 || a1 > a2)
AG> // ...
AG> [[noexcept]]
AG> {
AG> // а здесь мы что-то вызвали, что не бросает, но компилятор не знает об этом
AG> }
AG>}
AG>
noexcept(auto) пока нет (где-нибудь в районе C++1917 появится, вероятно), а вот [[noexcept]] вполне можно сымитировать уже сейчас:
[&]() noexcept
{
// а здесь мы что-то вызвали, что не бросает, но компилятор не знает об этом
}();