На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: Qraizer, Hsilgos
Страницы: (6) « Первая ... 2 3 [4] 5 6  все  ( Перейти к последнему сообщению )  
> как скопировать модификатор noexcept в свою функцию?
    Цитата Олег М @
    Тебе не кажется, что что–то ты делаешь неправильно? Не должен модификатор nothrow зависеть от слова protected

    Делаю правильно. А вот тестировать захотел слишком много.

    Банально, попытался унаследовать noexcept, с помощью постороннего класса. Сейчас прописываю всё руками, через noexcept( noexcept( ... ) ) и оно вроде даже наследуется, если судить по результатам тестов.
      Цитата Eric-S @
      Кстати, а разве можно создать экземпляр класса abstract?

      Ну надо же как-то скопировать модификатор из protected метода abstract класса, в public метод final класса?


      Не лучше ли его там явно указать? Или сделать using base_class::method;, в public:?
        Цитата Олег М @
        Не лучше ли его там явно указать? Или сделать using base_class::method;, в public:?

        Ой, нет. дело совсем не в том.

        Вот у меня конструктор
        ExpandedWrap disabled
          D() noexcept( noexcept( base_type() ) ):
          base_type()
          {
          ...
          }


        Так и получается, что внутри объекта класса D, создаётся объект класса base_type.

        Я по началу писал std::is_nothrow_default_constructible< base_type >::value и он всегда возвращал мне false.


        Когда я написал noexcept( base_type() ), то компиль сказал, что нельзя создать объект абстрактного класса.

        В итоге плюнул на носледование noexcept и написал проще:
        ExpandedWrap disabled
          D() noexcept( false )
          {
          ...
          }


        Если есть сомнение, что где-то, кто-то, когда-то бросит исключение, то он наверняка его бросит.
          Вот такой код у меня вроде нормально отработал - выдал warning, там где положено
          ExpandedWrap disabled
            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
          Сообщение отредактировано: Олег М -
            Цитата Олег М @
            std::is_nothrow_constructible<CTestBase>::value

            Он будет корректным, только пока CTestBase останется открытым классом.
            А если его конструктор сделать protected и добавить ключевое слово abstract в объявлении, то всё сломается.

            Так и должно быть, по логике наследования и защиты. Но в таком случае не получается скопировать модификатор noexcept у конструктора.
              Цитата Eric-S @
              А если его конструктор сделать protected и добавить ключевое слово abstract в объявлении, то всё сломается.

              У меня с ним почему-то не компилится, я пытался

              Добавлено
              Но на самом деле, я думаю, что это не слишком хорошая практика - так объявлять noexcept для методов. Ухудшает читабельность кода.
              Лучше, наверное, сделать так

              ExpandedWrap disabled
                    CTest(int n) noexcept
                    : CTestBase(n)
                    {
                        static_assert(std::is_nothrow_constructible<CTestBase, int>::value);
                    }
                Цитата Олег М @
                Вот такой код у меня вроде нормально отработал - выдал warning, там где положено

                Этот приём называется подгонкой условий задачи под правильный ответ.

                Усилия оценил. Да, всё верно, так действительно должно работать.

                Но крайне желательно, чтоб CTestBase был именно закрытым классом. Чтоб пользователь не мог создать его объекта.

                Добавлено
                Цитата Олег М @
                У меня с ним почему-то не компилится, я пытался

                Ха-эм... Наверное gcc не поддерживает.
                  Соответственно
                  ExpandedWrap disabled
                        void CTest::func() noexcept
                        {
                            static_assert(noexcept(CTestBase::func()));
                            CTestBase::func();
                        }
                    Цитата Олег М @
                    Но на самом деле, я думаю, что это не слишком хорошая практика - так объявлять noexcept для методов. Ухудшает читабельность кода.


                    Впринципе да, ухудшает.

                    Но у меня обёртка для неизвестного объекта value_type, с кучей заранее неизвестных факторов.

                    Вот и хочется прогнуться под объект. Если у того объекта конструкторы, деструкторы и прочие сервисные члены noexcept( true ), так это замечательно.
                    Но вдруг у него что-то объявлено, как noexcept( false ), а моя обёртка это исключение перехватит и уронит прогу?

                    Ради читабельности, мне придётся всё объявлять noexcept( false ). Только в этом случае, вложенный объект будет корректно обработан. Пусть и с дополнительными накладными расходами.

                    Правильнее будет аккуратно скопировать модификатор noexcept из чужого объекта и сделать у себя такой же модификатор.
                    Да, читабельность из-за этого всего сломается. Это уж наверняка. Но зато поднимется юзабельность.

                    И ещё, такой момент. Некоторые члены базового класса зависят от членов дочернего класса. Точнее от одной из нескольких специализаций дочернего класса. А там, модификаторы noexcept вообще прибиты гвоздями. В некоторых случаях, я скопировал из value_type. А в другой специализации использовал хак и заведомо поставил noexcept( true ). Так что модификаторы уже не зависят от самого объекта.
                    Сообщение отредактировано: Eric-S -
                      Цитата Eric-S @
                      мне придётся всё объявлять noexcept( false )

                      Это т.е. не объявлять модификатор noexcept вообще?
                        Цитата Олег М @
                        Это т.е. не объявлять модификатор noexcept вообще?

                        Э, нет! Не знаю как в gcc. А msvc если модификатор noexcept не проставлен, то проставляет их на своё усмотрение. Так что именно, надо проставлять руками, везде, явно noexcept( false ). В таком случае компилятор поймёт и не будет умничать.
                          Цитата Eric-S @
                          А msvc если модификатор noexcept не проставлен, то проставляет их на своё усмотрение.

                          Это где написано? Что-то очень сомневаюсь, чтоб компилятор мог привести к вызову terminate.
                            Цитата Олег М @
                            Это где написано? Что-то очень сомневаюсь, чтоб компилятор мог привести к вызову terminate.

                            https://msdn.microsoft.com/ru-ru/library/dn818588.aspx
                              Кстати, в gcc можно ещё вот такую весёлую штуку сделать
                              ExpandedWrap disabled
                                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();
                                    }
                                 
                                };


                              С шаблонами пока не смог придумать как
                              Сообщение отредактировано: Олег М -
                                Цитата Олег М @
                                Кстати, в gcc можно ещё вот такую весёлую штуку сделать

                                А что в результате она даст?
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (6) « Первая ... 2 3 [4] 5 6  все


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0511 ]   [ 16 queries used ]   [ Generated: 2.05.24, 06:25 GMT ]