Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.137.217.163] |
|
Страницы: (6) 1 2 [3] 4 5 ... Последняя » все ( Перейти к последнему сообщению ) |
Сообщ.
#31
,
|
|
|
Цитата Eric-S @ Если в каких-то компиляторах сделано, то это не значит, что принято в стандарте и наоборот. Скорее наоборот. Microsoft всегда довольно сильно отставал от стандарта. Ну да ладно. В твоём случае, по-моему, надо смотреть в сторону std::enable_if и std::condition. Вроде constexpr-функции можно передавать в качестве аргумента шаблона |
Сообщ.
#32
,
|
|
|
Цитата Олег М @ Цитата 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. Заметил тут забавную штуку. Если просто написать выражение template< typename T > class someclass { public: someclass() noexcept( bla_bla_bla ) }; то оно компилируется. Но если запросить модификатор noexcept, то тогда это выражение проверяется. cout << "someclass noexcept = " << noexcept( someclass() ) << endl; И в случае если выражение кривое, то падает с ошибкой компиляции. Так что я сейчас буду допиливать свой шаблонный класс и тестить его. А уж потом подумаю над некоторой оптимизацией. Добавлено Не имею понятия. Я не гуру. А программированием лишь балуюсь, время от времени. Так... Только поверхам нахватался всяких простых вещей. Ну, э-э-э, как вывести текст в консоль или как прочитать ввод и ещё немного сверх этого. А современную официальную спецификацию C++ на английском, даже не читал. Добавлено Цитата Олег М @ надо смотреть в сторону std::enable_if и std::condition. Вроде constexpr-функции можно передавать в качестве аргумента шаблона Всё же задумался, как же там реализовать. Ну ладно, для compile-time понятно, как выбрать ветку. 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, там же одно условие, которое проверяет динамической значение константы. |
Сообщ.
#33
,
|
|
|
Цитата Олег М @ Опять же. По-моему, очень плохая мысль бросать исключение из деструктора. Недоудалённые объекты и всё такое. Угу. Не все гениальные предложения Александреску одинаково полезны... |
Сообщ.
#34
,
|
|
|
Цитата Eric-S @ Не имею понятия. Я не гуру. А программированием лишь балуюсь, время от времени. Так... Я тоже не претендую. Но ты вроде выше описывал статический полиморфизм. Просто прикинь, не попадает ли то что я показал под эту концепцию. Добавлено Цитата Eric-S @ А у gcc, вроде бы до сих пор нет предкомпилированных хидеров. Ну и хрен сними. Там и заголовков майкрософтовских нет. Зато они 17 стандарт поддерживают, концепты и все дела. Добавлено Цитата Eric-S @ И в случае если выражение кривое, то падает с ошибкой компиляции. Потому что ты инстанциирвоал функцию. Если ты в шаблонном классе сделал функцию, но не вызвал ее, компилятор забивает на ошибки Добавлено Цитата Eric-S @ Ой, да ну. Пусть всё идёт в run-time, там же одно условие, которое проверяет динамической значение константы Сдался? Не стоит, там есть решение. Хотя, тоже не знаю какое |
Сообщ.
#35
,
|
|
|
Цитата Олег М @ Потому что ты инстнциироал функцию. Если ты в шаблонном кассе сделал функцию, но не вызвал ее, компилятор забивает на ошибки Фигня какая-то. Я специально, для отлова ошибок, инстанцировал явно весь шаблон класса, со всеми его предками. Сейчас сижу и набиваю проверки noexcept, через static_assert. С одним шаблонным классом вроде прокатило нормально, а с главным классом всё облом. Он мне упорно говорит, что у меня конструктор noexcept( false). Если я напишу явно noexcept( true ) тогда да, всё норм. А когда наследую noexcept от конструктора базового класса, то ой, опять false. Добавлено Цитата Олег М @ Но ты вроде выше описывал статический полиморфизм. Просто прикинь, не попадает ли то что я показал под эту концепцию. Из того, что ты написал, я не очень понял, кто там от кого. Ибо есть незнакомые слова, о смысле которых я могу лишь догадываться. Да, вроде статический полиморфизм, судя по вызовам в функции. Но он же, этот статический полиморфизм был и раньше. |
Сообщ.
#36
,
|
|
|
Цитата Eric-S @ Фигня какая-то. Я специально, для отлова ошибок, инстанцировал явно весь шаблон класса, со всеми его предками. Очевидно, не весь. |
Сообщ.
#37
,
|
|
|
Цитата Олег М @ Сдался? Не стоит, там есть решение. Хотя, тоже не знаю какое Даже не брался по серьёзному. Так, Только немного задумался. Сейчас грызу noexcept, по сабжу данной темы. Чего-то опять не сходится ожидаемое с получаемым. |
Сообщ.
#38
,
|
|
|
Цитата Eric-S @ Да, вроде статический полиморфизм, судя по вызовам в функции. Но он же, этот статический полиморфизм был и раньше Раньше ты в шаблоне не мог указать какие функции должны присутствовать у класса. Добавлено Цитата Eric-S @ Сейчас сижу и набиваю проверки noexcept, через static_assert Кстати, это хорошая идея. |
Сообщ.
#39
,
|
|
|
Цитата Олег М @ Очевидно, не весь. Ну вот у меня четыре шаблонных класса 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; ... }; Я их инстанцирую. 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. |
Сообщ.
#40
,
|
|
|
Цитата Eric-S @ Или, шаблонный класс, надо как-то иначе инстанцировать? Я вообще не вижу, чтоб ты их инстанциировал. Надо как–то переменные от них обьявить Добавлено А чтоб методы – надо их вызвать |
Сообщ.
#41
,
|
|
|
Цитата Олег М @ Я вообще не вижу, чтоб ты их инстанциировал. Дык, а это: template class D< stub, true >; А в хидере написано: extern template class D< stub, true >; Чтоб компилятор не инстанцировал этот шаблон в других объектных файлах, а искал уже готовый код. Добавлено Цитата Олег М @ Надо как–то переменные от них обьявить А чтоб методы – надо их вызвать Это в простом случае. Но тогда инстанциируется только то, что вызывается. И да, оно у меня в тестах, почти всё вызывается. Примерно покрытие кода тестами на 80%. Руки не дошли протестировать операторы сравнения и парочку методов. |
Сообщ.
#42
,
|
|
|
Цитата Eric-S @ то оно компилируется. Но если запросить модификатор noexcept, то тогда это выражение проверяется. cout << "someclass noexcept = " << noexcept( someclass() ) << endl; И в случае если выражение кривое, то падает с ошибкой компиляции А попробуй создать здесь просто экземпляр класса. Что выяснить, что проблема не в noexcept |
Сообщ.
#43
,
|
|
|
Цитата Олег М @ А попробуй создать здесь просто экземпляр класса. Что выяснить, что проблема не в noexcept У меня куча модульных тестов и по ним всё штатно отрабатывает. Так что на корректность кода, нареканий нет. Но я всё же понял в чём был косяк. 1. я проверял конструктор через std::is_nothrow_default_constructible. 2. конструктор был protected. 3. класс был abstract. Ну.. Проверял ещё кучу условий, всякие там вложенные объекты, пустые специализации шаблонов и прочее и прочее. Я попробовал убрать protected, но нет, не работает, вернул. Я попробовал убрать abstract, но нет, тоже не работает, вернул. Вот когда я убрал вместе сразу protected и abstract, то проверка прошла успешно. Блин!!! Вот я тупой! это же is_nothrow_default_constructible шаблонный клас, и он тупо не мог получить доступа к защищённому члену! |
Сообщ.
#44
,
|
|
|
Цитата Eric-S @ Вот когда я убрал вместе сразу protected и abstract, то проверка прошла успешно. Блин!!! Вот я тупой! это же is_nothrow_default_constructible шаблонный клас, и он тупо не мог получить доступа к защищённому члену! Тебе не кажется, что что–то ты делаешь неправильно? Не должен модификатор nothrow зависеть от слова protected Добавлено Кстати, а разве можно создать экземпляр класса abstract? |
Сообщ.
#45
,
|
|
|
Цитата Олег М @ Кстати, а разве можно создать экземпляр класса abstract? Ну надо же как-то скопировать модификатор из protected метода abstract класса, в public метод final класса? |