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

    Скорее наоборот. Microsoft всегда довольно сильно отставал от стандарта.
    Ну да ладно. В твоём случае, по-моему, надо смотреть в сторону std::enable_if и std::condition. Вроде constexpr-функции можно передавать в качестве аргумента шаблона
    Сообщение отредактировано: Олег М -
      Цитата Олег М @
      Цитата Eric-S @
      Концепт, в моём понимании, это специальный тип, который создаёт интерфейс для объектов со статическим полиморфизмом.

      А это не template?

      Не. template создаёт тип по шаблону. У этих типов могут быть одинаковые статические интерфейсы, но не всегда и не обязательно. Особенно если наделать разных специализаций.

      Динамический (виртуальный) полиморфизм, это когда есть интерфейс (класс с чисто виртуальными функциями). А другие классы реализуют этот интерфейс, переопределяя виртуальные функции. Но доступ к таким членам происходит динамически через таблицу виртуальных функций.

      Статический полиморфизм, это когда некий интерфейс подразумевается, но нигде не прописан. Просто у разных класов есть функции с одинаковыми названиями, одинаковыми параметрами и одинаковыми возвращаемыми значениями. Шаблонные функции могут принимать объекты разных классов и совершать с ними одинаковые действия. Например "back_inserter" или "front_inserter" могут принимать любые колекции с одинаковым статическим интерфейсом. Доступ к членам объектов со статическим полиморфизмом происходит без дополнительных расходов на вызов.

      Вот это, всё, как бы хорошо. Но одно противопостовляется другому.

      Функция которая юзает объект с динамическим полиморфизмом, может быть скомпилирована и помещена в исполняемый код библиотеки. Такая функция принимает только ссылку или указатель на объект. Но если тип объекта не унаследовал и нереализовал специальный виртуальный интерфейс, то обломс!

      Функция которая юзает объект со статическим полиморфизмом, может быть только шаблонной! Она обязана размещатся только в хидере. И компилятор, для каждого варианта функции с новыми типами, создаёт свой инстанс.

      А вот концепт, он реализует этакий адаптер, оборачивающий произвольный объект и предоставляющий к нему динамический интерфейс. То есть в параметры скомпилированной функции, можно передавать объекты со статическим полиморфизмом.
      Или даже объекты у которых нет таково интерфейса.

      Кстати, функции std::begin и std::end примерно так же обёртывают объект произвольного типа и возвращают итераторы. Это конечно не концепт, но что-то в этом есть.

      А вот класс string_view ещё ближе к реализации одного из концептов. Обёртывает std::basic_string или char* и предоставляет единый интерфейс к строке.

      Добавлено
      Цитата Олег М @
      Microsoft всегда довольно сильно отставал от стандарта.

      Не всегда. Что-то они реализовывали раньше и даже намного раньше выхода стандарта. А где-то совсем опережают, о чём стандарт даже и не думал. Другие компиляторы делают так же. Например модули запилили в msvc и clang, а в стандарте их ещё обсуждают. А у gcc, вроде бы до сих пор нет предкомпилированных хидеров.

      Добавлено
      Цитата Олег М @
      В твоём случае, по-моему, надо смотреть в сторону std::enable_if и std::condition. Вроде constexpr-функции можно передавать в качестве аргумента шаблона

      Я ещё долблюсь с этим noexcept.
      Заметил тут забавную штуку.
      Если просто написать выражение
      ExpandedWrap disabled
        template< typename T >
        class someclass
        {
        public:
         
        someclass() noexcept( bla_bla_bla )
         
        };

      то оно компилируется.
      Но если запросить модификатор noexcept, то тогда это выражение проверяется.
      ExpandedWrap disabled
        cout << "someclass noexcept = " << noexcept( someclass() ) << endl;

      И в случае если выражение кривое, то падает с ошибкой компиляции.

      Так что я сейчас буду допиливать свой шаблонный класс и тестить его. А уж потом подумаю над некоторой оптимизацией.

      Добавлено
      Цитата Олег М @
      Но, разве IsSharedMutex не определяет именно такой интерфейс, или IsFormatable?

      Не имею понятия. Я не гуру. А программированием лишь балуюсь, время от времени. Так... Только поверхам нахватался всяких простых вещей. Ну, э-э-э, как вывести текст в консоль или как прочитать ввод и ещё немного сверх этого. А современную официальную спецификацию C++ на английском, даже не читал.

      Добавлено
      Цитата Олег М @
      надо смотреть в сторону std::enable_if и std::condition. Вроде constexpr-функции можно передавать в качестве аргумента шаблона

      Всё же задумался, как же там реализовать.
      Ну ладно, для compile-time понятно, как выбрать ветку.

      ExpandedWrap disabled
        void _if_set_value( const_reference value, false_type )
        {
        _construct( value );
        }
         
        void _if_set_value( const_reference value, true_type )
        {
        _assign( value );
        }
         
        void _if_set_value( value_reference value )
        {
        typedef typename condition< is_good(), true_type, false_type >::type variant_type;
        _if_set_value( value, variant_type() );
        }


      А как выбрать ветку для run-time?

      Ой, да ну. Пусть всё идёт в run-time, там же одно условие, которое проверяет динамической значение константы.
        Цитата Олег М @
        Опять же. По-моему, очень плохая мысль бросать исключение из деструктора. Недоудалённые объекты и всё такое.

        Угу. Не все гениальные предложения Александреску одинаково полезны...
          Цитата Eric-S @
          Не имею понятия. Я не гуру. А программированием лишь балуюсь, время от времени. Так...

          Я тоже не претендую. Но ты вроде выше описывал статический полиморфизм. Просто прикинь, не попадает ли то что я показал под эту концепцию.

          Добавлено
          Цитата Eric-S @
          А у gcc, вроде бы до сих пор нет предкомпилированных хидеров.

          Ну и хрен сними. Там и заголовков майкрософтовских нет. Зато они 17 стандарт поддерживают, концепты и все дела.

          Добавлено
          Цитата Eric-S @
          И в случае если выражение кривое, то падает с ошибкой компиляции.

          Потому что ты инстанциирвоал функцию. Если ты в шаблонном классе сделал функцию, но не вызвал ее, компилятор забивает на ошибки

          Добавлено
          Цитата Eric-S @

          Ой, да ну. Пусть всё идёт в run-time, там же одно условие, которое проверяет динамической значение константы

          Сдался?
          Не стоит, там есть решение. Хотя, тоже не знаю какое
          Сообщение отредактировано: Олег М -
            Цитата Олег М @
            Потому что ты инстнциироал функцию. Если ты в шаблонном кассе сделал функцию, но не вызвал ее, компилятор забивает на ошибки

            Фигня какая-то. Я специально, для отлова ошибок, инстанцировал явно весь шаблон класса, со всеми его предками.

            Сейчас сижу и набиваю проверки noexcept, через static_assert.

            С одним шаблонным классом вроде прокатило нормально, а с главным классом всё облом.
            Он мне упорно говорит, что у меня конструктор noexcept( false). Если я напишу явно noexcept( true ) тогда да, всё норм. А когда наследую noexcept от конструктора базового класса, то ой, опять false.

            Добавлено
            Цитата Олег М @
            Но ты вроде выше описывал статический полиморфизм. Просто прикинь, не попадает ли то что я показал под эту концепцию.

            Из того, что ты написал, я не очень понял, кто там от кого. Ибо есть незнакомые слова, о смысле которых я могу лишь догадываться.
            Да, вроде статический полиморфизм, судя по вызовам в функции. Но он же, этот статический полиморфизм был и раньше.
              Цитата Eric-S @

              Фигня какая-то. Я специально, для отлова ошибок, инстанцировал явно весь шаблон класса, со всеми его предками.

              Очевидно, не весь.
                Цитата Олег М @
                Сдался?
                Не стоит, там есть решение. Хотя, тоже не знаю какое

                Даже не брался по серьёзному. Так, Только немного задумался.
                Сейчас грызу noexcept, по сабжу данной темы. Чего-то опять не сходится ожидаемое с получаемым.
                  Цитата Eric-S @
                  Да, вроде статический полиморфизм, судя по вызовам в функции. Но он же, этот статический полиморфизм был и раньше

                  Раньше ты в шаблоне не мог указать какие функции должны присутствовать у класса.

                  Добавлено
                  Цитата Eric-S @

                  Сейчас сижу и набиваю проверки noexcept, через static_assert

                  Кстати, это хорошая идея.
                    Цитата Олег М @
                    Очевидно, не весь.

                    Ну вот у меня четыре шаблонных класса
                    ExpandedWrap disabled
                      template< type T > union a{ ... };
                       
                      template< type T > class B abstract { typedef T value_type; ... };
                       
                      template< type T, bool F > class C abstract;
                       
                      template< type T > class C< T, false > abstract: public B< T > { ... };
                       
                      template< type T > class C< T, true > abstract: public B< T > { ... };
                       
                      template< typename T, bool F = false > class D final: public C< T, F > { typedef C< T, F > base_type; typedef typename base_type::value_type value_type; ... };


                    Я их инстанцирую.

                    ExpandedWrap disabled
                      template union A< stub >;
                      template class B< stub >;
                      template class B< stub >;
                      template class C< stub, false >;
                      template class C< stub, true >;
                      template class D< stub, false >;
                      template class D< stub, true >;


                    Или, шаблонный класс, надо как-то иначе инстанцировать?
                    Если я делаю ошибки в коде этих классов, то компилятор сразу ругается. А без инстанцирования молчит.

                    Единственное, грешу, на класс C, для которого у меня две специализации.

                    Там даже была накладка с наследованием типа. Пришлось явно тащить typedef value_type.

                    Возможно он точно так же не находит конструктор класса C.
                      Цитата Eric-S @

                      Или, шаблонный класс, надо как-то иначе инстанцировать?

                      Я вообще не вижу, чтоб ты их инстанциировал.
                      Надо как–то переменные от них обьявить

                      Добавлено
                      А чтоб методы – надо их вызвать
                      Сообщение отредактировано: Олег М -
                        Цитата Олег М @
                        Я вообще не вижу, чтоб ты их инстанциировал.

                        Дык, а это:
                        ExpandedWrap disabled
                          template class D< stub, true >;


                        А в хидере написано:
                        ExpandedWrap disabled
                          extern template class D< stub, true >;


                        Чтоб компилятор не инстанцировал этот шаблон в других объектных файлах, а искал уже готовый код.

                        Добавлено
                        Цитата Олег М @
                        Надо как–то переменные от них обьявить
                        А чтоб методы – надо их вызвать

                        Это в простом случае. Но тогда инстанциируется только то, что вызывается.
                        И да, оно у меня в тестах, почти всё вызывается. Примерно покрытие кода тестами на 80%. Руки не дошли протестировать операторы сравнения и парочку методов.
                          Цитата Eric-S @
                          то оно компилируется.
                          Но если запросить модификатор noexcept, то тогда это выражение проверяется.

                          cout << "someclass noexcept = " << noexcept( someclass() ) << endl;

                          И в случае если выражение кривое, то падает с ошибкой компиляции


                          А попробуй создать здесь просто экземпляр класса. Что выяснить, что проблема не в noexcept
                            Цитата Олег М @
                            А попробуй создать здесь просто экземпляр класса. Что выяснить, что проблема не в noexcept

                            У меня куча модульных тестов и по ним всё штатно отрабатывает. Так что на корректность кода, нареканий нет.

                            Но я всё же понял в чём был косяк.
                            1. я проверял конструктор через std::is_nothrow_default_constructible.
                            2. конструктор был protected.
                            3. класс был abstract.

                            Ну.. Проверял ещё кучу условий, всякие там вложенные объекты, пустые специализации шаблонов и прочее и прочее.

                            Я попробовал убрать protected, но нет, не работает, вернул.
                            Я попробовал убрать abstract, но нет, тоже не работает, вернул.
                            Вот когда я убрал вместе сразу protected и abstract, то проверка прошла успешно.

                            Блин!!! Вот я тупой! это же is_nothrow_default_constructible шаблонный клас, и он тупо не мог получить доступа к защищённому члену!
                            Сообщение отредактировано: Eric-S -
                              Цитата Eric-S @
                              Вот когда я убрал вместе сразу protected и abstract, то проверка прошла успешно.

                              Блин!!! Вот я тупой! это же is_nothrow_default_constructible шаблонный клас, и он тупо не мог получить доступа к защищённому члену!

                              Тебе не кажется, что что–то ты делаешь неправильно? Не должен модификатор nothrow зависеть от слова protected

                              Добавлено
                              Кстати, а разве можно создать экземпляр класса abstract?
                                Цитата Олег М @
                                Кстати, а разве можно создать экземпляр класса abstract?

                                Ну надо же как-то скопировать модификатор из protected метода abstract класса, в public метод final класса?
                                1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                                0 пользователей:


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0513 ]   [ 15 queries used ]   [ Generated: 17.05.24, 20:02 GMT ]