С Новым годом! Форум программистов, компьютерный форум, киберфорум
Visual C++
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.81/21: Рейтинг темы: голосов - 21, средняя оценка - 4.81
фрилансер
5846 / 5377 / 1103
Регистрация: 11.10.2019
Сообщений: 14,376
1

VS2019 и noexcept

05.12.2023, 17:31. Показов 4358. Ответов 6
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
имеется вот такой код. Вижуал студия 2019 жужжит на строку 27, я не понимаю, почему

C++17
https://onlinegdb.com/C9LxFbe-e
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
#include <algorithm>
#include <set>
 
int main()
{
    std::set<int> s1, s2;
    static_assert(noexcept(std::swap(s1, s2)));
 
    struct B
    {
        std::set<int> s;
 
        void swap(B& r)noexcept
        {
            std::swap(*this, r);
        }
    };
    B b1, b2;
    static_assert(noexcept(b1.swap(b2)));
 
    struct A
    {
        std::set<int> s;
    };
    A a1, a2;
    static_assert(noexcept(std::swap(a1, a2)));//VS2019: static assertion failed
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
05.12.2023, 17:31
Ответы с готовыми решениями:

Noexcept и throw()
здравствуйте, подскажите, в каких случаях нужно использовать noexcept за исключением деструкторов и...

noexcept возвращает значение?
Прототип std::swap выглядит так: template &lt;class T, size_t N&gt; void swap(T (&amp;a), T (&amp;b)) noexcept...

Почему нужно noexcept?
Здравствуйте. Сразу код :) : class logic_error_ext : public std::exception { private: ...

Noexcept - рекомендации по применению
У меня вопрос - есть ли какие то правила по применению этого ключевого слова на практике? Когда...

6
фрилансер
5846 / 5377 / 1103
Регистрация: 11.10.2019
Сообщений: 14,376
07.12.2023, 09:26  [ТС] 2
0
19409 / 10028 / 2443
Регистрация: 30.01.2014
Сообщений: 17,678
07.12.2023, 11:29 3
Лучший ответ Сообщение было отмечено Алексей1153 как решение

Решение

Алексей1153, потому что у А operator=(A&&) и\или A(A&&) не noexcept.

Добавлено через 9 минут
Алексей1153, у std::set перемещающий конструктор не обозначен как noexcept:
https://en.cppreference.com/w/... er/set/set (см. номер 8)
Поэтому и A(A&&) будет не-noexcept.

Добавлено через 3 минуты
Вот так можно подавить ассерт, однако правильно ли это будет в принципе - не ясно.
C++
1
2
3
4
5
6
7
8
9
    struct A
    {
        std::set<int> s;
        A() = default;
        A(A&&) noexcept = default;
        A& operator=(A&&) noexcept = default;
    };
    A a1, a2;
    static_assert(noexcept(std::swap(a1,a2)));
Нужно разбираться в каких случаях std::set бросает исключения из конструктора.

Или возможно это просто дефект стандарта. К сожалению у меня сейчас нет возможности поискать документ об исправлении, если он был вообще.
В любом случае MSVC сейчас просто следует правилам (https://eel.is/c++draft/associative#set.overview-2), а в GCC этот конструктор помечен noexcept уже самовольно (поэтому пример работает в онлайн компиляторе).
1
фрилансер
5846 / 5377 / 1103
Регистрация: 11.10.2019
Сообщений: 14,376
07.12.2023, 11:32  [ТС] 4
Цитата Сообщение от DrOffset Посмотреть сообщение
у std::set перемещающий конструктор не обозначен как noexcept:
да, точно. Странно, почему так
И почему тогда 8-я строка нормально воспринимается

Цитата Сообщение от DrOffset Посмотреть сообщение
подавить ассерт
нет, подавлять не требуется
0
19409 / 10028 / 2443
Регистрация: 30.01.2014
Сообщений: 17,678
07.12.2023, 12:26 5
Лучший ответ Сообщение было отмечено Алексей1153 как решение

Решение

Цитата Сообщение от Алексей1153 Посмотреть сообщение
И почему тогда 8-я строка нормально воспринимается
Потому что std::swap перегружен специально для std::set как noexcept (он использует std::set::swap, который noexcept в большинстве случаев).
Так что видимо в случае из поста наиболее правильным будет перегрузить swap для A.
1
фрилансер
5846 / 5377 / 1103
Регистрация: 11.10.2019
Сообщений: 14,376
07.12.2023, 12:52  [ТС] 6
DrOffset, понятно, спасибо

Добавлено через 9 минут
как-то так, значит

C++
1
2
3
4
5
6
7
8
9
10
11
struct A
{
    std::set<int> s;
    friend void swap(A& l,A& r)noexcept
    {
        std::swap(l.s, r.s);
    }
};
 
A a1, a2;
static_assert(noexcept(swap(a1, a2)));

студия согласная

Добавлено через 1 минуту
только каждое поле вручную надо не забыть свопнуть
0
Вездепух
Эксперт CЭксперт С++
12792 / 6669 / 1795
Регистрация: 18.10.2014
Сообщений: 16,876
12.12.2023, 18:13 7
Лучший ответ Сообщение было отмечено Алексей1153 как решение

Решение

Причина, по которой специальные методы класса std::set не являются noexcept периодически всплывают в разных контекстах. Ответ на эту тему можно найти здесь

https://developercommunity.vis... onstructor

Стандарт не требует того, чтобы перемещающие операции std::set были noexcept. Однако в libstdc++ (GCC и Clang) их таки сделали noexcept. В VS они не являются noexcept, потому, что каждый контейнер требует выделения своего индивидуального guard element.

Цитата Сообщение от Алексей1153 Посмотреть сообщение
только каждое поле вручную надо не забыть свопнуть
Если решать проблему просто грубой навеской noexcept, то это можно сделать так

C++
1
2
3
4
5
6
7
8
  struct A
  {
    A() = default;
    A(A&&) noexcept = default;
    A& operator =(A&&) noexcept = default;
 
    std::set<int> s;
  };
Так ничего не нужно больше делать вручную для каждого поля. И ваш static_assert перестанет "стрелять".
1
12.12.2023, 18:13
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
12.12.2023, 18:13
Помогаю со студенческими работами здесь

Что такое noexcept
noexcept

Ключевое слово noexcept
Прочитал про noexcept и понял, что его нужно использовать для тех методов, которые не бросают...

Когда нужно использовать noexcept
Когда нужно использовать noexcept? В любом методе который 99.9% работает без исключений ?

Оператор noexcept и перегруженные методы класса
Всем привет Как проверить с помощью noexcept, кидает ли исключение нужный мне перегруженный метод?...

Требует ли стандарт noexcept деструкторов для классов STL?
Я проверил вот такую программку на трех онлайн-компиляторах: #include &lt;iostream&gt; #include...

Дизассемблер в VS2019
Есть ли на vs2019 расширение, которое при нажатии ctrl+лкм на каком-нибудь классе покажет мне...

ifstream VS2019
Добрый день ув. форумчане. Написал код для чтения данных в бинарном виде. После попадания на...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru