Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.138.175.180] |
|
Страницы: (6) « Первая ... 2 3 [4] 5 6 все ( Перейти к последнему сообщению ) |
Сообщ.
#46
,
|
|
|
Цитата Олег М @ Тебе не кажется, что что–то ты делаешь неправильно? Не должен модификатор nothrow зависеть от слова protected Делаю правильно. А вот тестировать захотел слишком много. Банально, попытался унаследовать noexcept, с помощью постороннего класса. Сейчас прописываю всё руками, через noexcept( noexcept( ... ) ) и оно вроде даже наследуется, если судить по результатам тестов. |
Сообщ.
#47
,
|
|
|
Цитата Eric-S @ Кстати, а разве можно создать экземпляр класса abstract? Ну надо же как-то скопировать модификатор из protected метода abstract класса, в public метод final класса? Не лучше ли его там явно указать? Или сделать using base_class::method;, в public:? |
Сообщ.
#48
,
|
|
|
Цитата Олег М @ Не лучше ли его там явно указать? Или сделать using base_class::method;, в public:? Ой, нет. дело совсем не в том. Вот у меня конструктор D() noexcept( noexcept( base_type() ) ): base_type() { ... } Так и получается, что внутри объекта класса D, создаётся объект класса base_type. Я по началу писал std::is_nothrow_default_constructible< base_type >::value и он всегда возвращал мне false. Когда я написал noexcept( base_type() ), то компиль сказал, что нельзя создать объект абстрактного класса. В итоге плюнул на носледование noexcept и написал проще: D() noexcept( false ) { ... } Если есть сомнение, что где-то, кто-то, когда-то бросит исключение, то он наверняка его бросит. |
Сообщ.
#49
,
|
|
|
Вот такой код у меня вроде нормально отработал - выдал warning, там где положено
struct CTestBase { CTestBase() noexcept { } CTestBase(int) { } }; struct CTest : public CTestBase { CTest() noexcept(!std::is_nothrow_constructible<CTestBase>::value) { throw 1; } CTest(int) noexcept(!std::is_nothrow_constructible<CTestBase, int>::value) : CTestBase(n) { throw 1; //warning: throw will always call terminate() [-Wterminate] } }; Добавлено Под gcc |
Сообщ.
#50
,
|
|
|
Цитата Олег М @ std::is_nothrow_constructible<CTestBase>::value Он будет корректным, только пока CTestBase останется открытым классом. А если его конструктор сделать protected и добавить ключевое слово abstract в объявлении, то всё сломается. Так и должно быть, по логике наследования и защиты. Но в таком случае не получается скопировать модификатор noexcept у конструктора. |
Сообщ.
#51
,
|
|
|
Цитата Eric-S @ А если его конструктор сделать protected и добавить ключевое слово abstract в объявлении, то всё сломается. У меня с ним почему-то не компилится, я пытался Добавлено Но на самом деле, я думаю, что это не слишком хорошая практика - так объявлять noexcept для методов. Ухудшает читабельность кода. Лучше, наверное, сделать так CTest(int n) noexcept : CTestBase(n) { static_assert(std::is_nothrow_constructible<CTestBase, int>::value); } |
Сообщ.
#52
,
|
|
|
Цитата Олег М @ Вот такой код у меня вроде нормально отработал - выдал warning, там где положено Этот приём называется подгонкой условий задачи под правильный ответ. Усилия оценил. Да, всё верно, так действительно должно работать. Но крайне желательно, чтоб CTestBase был именно закрытым классом. Чтоб пользователь не мог создать его объекта. Добавлено Цитата Олег М @ У меня с ним почему-то не компилится, я пытался Ха-эм... Наверное gcc не поддерживает. |
Сообщ.
#53
,
|
|
|
Соответственно
void CTest::func() noexcept { static_assert(noexcept(CTestBase::func())); CTestBase::func(); } |
Сообщ.
#54
,
|
|
|
Цитата Олег М @ Но на самом деле, я думаю, что это не слишком хорошая практика - так объявлять noexcept для методов. Ухудшает читабельность кода. Впринципе да, ухудшает. Но у меня обёртка для неизвестного объекта value_type, с кучей заранее неизвестных факторов. Вот и хочется прогнуться под объект. Если у того объекта конструкторы, деструкторы и прочие сервисные члены noexcept( true ), так это замечательно. Но вдруг у него что-то объявлено, как noexcept( false ), а моя обёртка это исключение перехватит и уронит прогу? Ради читабельности, мне придётся всё объявлять noexcept( false ). Только в этом случае, вложенный объект будет корректно обработан. Пусть и с дополнительными накладными расходами. Правильнее будет аккуратно скопировать модификатор noexcept из чужого объекта и сделать у себя такой же модификатор. Да, читабельность из-за этого всего сломается. Это уж наверняка. Но зато поднимется юзабельность. И ещё, такой момент. Некоторые члены базового класса зависят от членов дочернего класса. Точнее от одной из нескольких специализаций дочернего класса. А там, модификаторы noexcept вообще прибиты гвоздями. В некоторых случаях, я скопировал из value_type. А в другой специализации использовал хак и заведомо поставил noexcept( true ). Так что модификаторы уже не зависят от самого объекта. |
Сообщ.
#55
,
|
|
|
Цитата Eric-S @ мне придётся всё объявлять noexcept( false ) Это т.е. не объявлять модификатор noexcept вообще? |
Сообщ.
#56
,
|
|
|
Цитата Олег М @ Это т.е. не объявлять модификатор noexcept вообще? Э, нет! Не знаю как в gcc. А msvc если модификатор noexcept не проставлен, то проставляет их на своё усмотрение. Так что именно, надо проставлять руками, везде, явно noexcept( false ). В таком случае компилятор поймёт и не будет умничать. |
Сообщ.
#57
,
|
|
|
Цитата Eric-S @ А msvc если модификатор noexcept не проставлен, то проставляет их на своё усмотрение. Это где написано? Что-то очень сомневаюсь, чтоб компилятор мог привести к вызову terminate. |
Сообщ.
#58
,
|
|
|
Цитата Олег М @ Это где написано? Что-то очень сомневаюсь, чтоб компилятор мог привести к вызову terminate. https://msdn.microsoft.com/ru-ru/library/dn818588.aspx |
Сообщ.
#59
,
|
|
|
Кстати, в gcc можно ещё вот такую весёлую штуку сделать
template <typename T = CTestBase> struct CTest : public T { void func() noexcept requires !noexcept(this->T::func()) { try { T::func(); } catch(...) { } } void func() noexcept requires noexcept(this->T::func()) { T::func(); } }; С шаблонами пока не смог придумать как |
Сообщ.
#60
,
|
|
|
Цитата Олег М @ Кстати, в gcc можно ещё вот такую весёлую штуку сделать А что в результате она даст? |