![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| Любитель |
|
||||
|
Программист-романтик ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3645 Регистрация: 21.5.2005 Где: Воронеж Репутация: 24 Всего: 92 |
Идея этой темы основана на теме про буст, которая плавно переползла в необходимость (или нет) стандартного ГУИ и другие подобные вопросы. Хотя впрочем мне хотелось начать подобное обсуждение давно. Признаюсь, что я находил старую тему с подобным делом (я в ней участия не принимал), но главный её недостаток в том, что она старая. Много изменилось с того времени (на мой взгляд), да и людей новых (по сравнению с тем временем) много. Потому...
Вообщем, хотелось бы обсудить, что бы вы хотели увидеть в новом C++ (C++0x). Пожалуй не будем разделять (совсем отдельно) языковые фичи и библиотеки, зачастую они переплетаются, да и картина так будет более полная. Вовсе не обязательно, чтобы то, что вы хотите одобрялось (сегодня) комитетом по стандартизации - интересно именно узнать мнения. Можно также писать "возможность X крайне не желательна". Желательно только аргументировать, хотя впрочем я понимаю, что часто думаешь, мне нужно бла-бла-бла, а зачем - фиг его знает. Но нужно! Чем больше будет мнений (надеюсь, что их будет достаточное количество) - тем интересней. Даже, если вы считаете, что ничего менять не надо - напишите, что C++ уже идеален, дальнейшее его развитие невозможно (или ненужно). Я же всё-таки считаю, что C++ - замечательнейший, но по современным требованиям недоработанный язык. Я считаю важным обеспечить возможность нормального создания библиотек на C++. Сейчас разрабатываются либы или под конкретный компилер (причём извратно), либо на уровне исходного кода. Шаблоны - одно из важнейших средств C++, тем не менее даже export поддерживают единицы компилеров (вроде Comeau), да и то требуют исходников. Конечно, шаблоны (естественно, речь про unmanaged) невозможно по определению скомпилировать, ибо это не готовый код (готовый код - специализации). Но некий промежуточный код можно стандартизировать. При компиляции проекта компилер будет докомпиливать этот код. Достаточно интересен вопрос темплейтов в динамик-либах, но здесь для меня пока всё туманно. Простого (более-менее) решения я не вижу, лишь внедрения вторичного компилятора в рантайм C++ (только для темплейтов), впрочем мне это что-то напоминает ;) . Кстати о динамик-либах, средств для работы с ними мы тоже не имеем. Причём мы должны иметь как синтаксис для компиляции либ, так и классы для их динамической загрузки, просмотра экспортируемых вещей и пр. В связи с этим (хотя не только с этим) возникает необходимость в более мощном RTTI, вплоть до получения адреса функции по её строковому имени. Необходимо также более чётко стандартизировать модель размещения объекта в памяти. Очень желательно так, чтобы мы могли гарантировано знать, что два компилера будут одинаково хранить объекты нашего (произвольной сложности) класса. Я всеми руками и ногами за уменьшение в стандарте implementation defined. Более того, я также требую стандартизации размеров встроенных типов данных. В конце концов в других языках это лишь облегчает жизнь. И посмотрите на добрую кучу библиотек - все определяют для себя типы с гарантированным размером. Не проще и не лучше ли гарантировать это на уровне языка. Исключение, возможно, стоит сделать для специфических вариаций на тему C++ (вроде Embedded C++), хотя по этой теме я вряд ли что скажу. Стандартизация всех этих вещей приводит нас к портируемости между компилерами готового кода. Также необходимо понятие "проекта" (можете называть это сборкой). Это не замена мейкфайлов (или их альтенатив вроде bjam, qmake, MSBuild и пр.), это нужно в первую очередб для библиотек. + это нас избавляет от явной работы с линкером, который для C++ выглядит всё-таки несколько чужим. В Design and Evolution of C++ мы читаем, что одной из целью служения классической линковке была сометсимость C++ с C и Fortran, чтобы можно было использовать их компоновщики. Бюсь это не дюже практично сегодня. Мы указываем в проекте, какие скомпилированные библиотеки мы используем (тоже проекты) и никакой прилинковки лишней не надо. Всё делается достаточно прозрачно. В числе нерешённых вопросов к комитету мне удалось найти вопрос о том, когда писать угловые скобки для заголовков, а когда кавычки. Была предложена иерархия: 1. Стандартная библиотека C++ (заголовки не обязаны быть файлами) 2. Другие стандартные либы, вроде POSIX 3. API оси (вроде WinaPI) 4. Сторонние либы (вроде буста) 5. "Стандартные" библиотеки компании 6. Общие хейдера проекта (для всех девелоперов) 7. Локальные хейдеры Повторюсь - вопрос не решён (где граница между кавычками и угловыми скобками). Кстати насчёт инклюда. Сегодня за препроцессором остались лишь условная компиляция и инклюды (остальное реализуемо лучше средставми языка). Есть конечно ещё прагмы и прочая гадось, но они по-моему не достойны столь высокого обсуждения. И если условная компиляция - естественная ниша препроцессора, то инклюд - ну уж нет. Необходимо сделать конструкцию языка инклюд с некоторыми защитами. Например, от дабл-инклюда, от действия юзингов в инклюде и пр. В связи с этим надо более точно определиться с понятиме хейдера. Более того, возможна даже компиляция хейдеров. Что это значит? А это значит извлечение в удобную для компилера форму интерфейса заголовка, для дальнейшего более быстрого использования. А теперь вспомните мои рассуждения о темплейтах... От такой философии вернёмся к будням программирования. Несколько кейвордов и возможностей. Что я за, что против. Возможно позже я напишу более подробно - пока краткий обзор. Поддерживаю: перегрузка операторов приведения, перегрузка функторов, свитчи для строк, определение типа енумов, alignof, restricted, real или explicit типедефы и енум (без неявного приведения к фактическому типу или целым числам), final/sealed. Также хотелось бы увидеть типобезопасную версию вараргов. Скажем так:
Компилер в состоянии сгенерить (по заголовку) код вызова такой функции, используя соглашения STL-контейнеров. Вдобавок такая функция (в отличие от сишной) может не иметь аргументов. А спомощью чего-то вроде boost::any получаем также произвольный тип аргументов. Аналогично неплохо бы добавить ещё одну версию main с контейнером (любым) из std::string. Безусловно можно написать что-то вроде
но согласитесь явное существование сигнатуры эстетически приятней. Естественно приведённый только что код должен работать (с двумя больше без пробела). Ещё надо как-то поругать производителей виндовых компилеров: нефиг выдумывать всякие WinMain! main и точка. Чтож либы похоже придётся оставить до следующего раза - и так много. Жду ваших мнений, в том числе замечаний по тому, что я написал (только сильно бить не надо...). Это сообщение отредактировал(а) Любитель - 4.11.2006, 12:23 |
||||
|
|||||
| MAKCim |
|
||||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 52 Всего: 207 |
Шаблоны в С++ - это абстракция времени компиляции. В этом вся фишка. Во время выполнения все типы известны, ничего выводить не надо и программа работает быстро и эффективно. Даже не представляю шаблоны в run-time
Это да Я бы добавил type list-ы ы шаблонах, шаблонные typedef-ы -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
||||
|
|||||
| UnrealMan |
|
||||||||||||||||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 722 Регистрация: 30.3.2006 Репутация: 27 Всего: 32 |
Категорически не согласен. Макросы всё ещё являются полноправным средством при написании программ на C++. Далеко не все абстракции можно выразить при помощи одних шаблонов, и, как следствие, отказ от макросов в ряде случаев повлечёт за собой либо необходимость многократно повторять один и тот же код с некоторыми изменениями, либо полностью отказаться от использования некоторых идиом. Макросы могут придавать наглядность коду и с этой точки зрения они иногда просто незаменимы. Приведу несколько примеров. 1) Реализация обобщённой «функции» min Допустим, на входе min мы имеем фактические параметры разных типов. Только лишь шаблонами тут обойтись нелегко – требуется решить нетривиальную задачу по установлению типа результата. С привлечением макросов проблема решается в 5 сек.:
2) Иногда макросы удобны для устранения из виду несущественных деталей кода. Рассмотрим шаблон:
А теперь возьмём такой пример: требуется составить шаблон, устанавливающий, является тип интегральным или нет. Я не буду приводить здесь реализацию шаблона IsArithmetical (этот шаблон определяет принадлежность типа к фундаментальным арифметическим типам), ибо в данном случае это не есть суть того, что я хочу показать. Что нагляднее в использовании: макрос
или непосредственное плюхание шаблона?
По-моему, первое читается несколько полегче. 3) В языке C++ пока что не предусмотрены манипуляции с шаблонами с переменным числом параметров. Поэтому иногда (например, при создании обобщённых функторов) требуется создавать серию вариантов шаблонов с разным количеством параметров. Когда-то я поставил перед собой задачу – сделать так, чтобы к итераторам можно было применять operator –>*. Вот примерная реализация:
Здесь придётся сделать несколько специализаций класса для разного кол-ва параметров. Это нудная и чреватая ошибками работа, которую как раз-таки лучше перепоручить препроцессору. Для этого достаточно лишь один раз определить серии макросов, где каждый последующий макрос определяется через предыдущий:
(вроде бы в boost нечто похожее есть, но по некоторым причинам я им не пользуюсь, а потому не могу продемонстрировать здесь пример с использованием boost, ибо не изучал и не знаю его). Теперь вышеприведённый пример с многоточием можно записать следующим образом:
Можно создавать и другие конструкции. Вот, например, реализация функции WriteLn:
Добиться такой простоты без применения макросов невозможно – по крайней мере, на данный момент. Впрочем, выводы делайте сами. Это сообщение отредактировал(а) UnrealMan - 4.11.2006, 09:38 |
||||||||||||||||||
|
|||||||||||||||||||
| sergejzr |
|
||||||
![]() Un salsero Профиль Группа: Админ Сообщений: 13285 Регистрация: 10.2.2004 Где: Германия г .Ганновер Репутация: 19 Всего: 360 |
Хмм.. Как вы реализуете с помощью языка:
Одно из самых лучших решений для вывода информации, которое я встречал. (dprintf("Hello"); выведет не только строку, но и позицию в исходнике, где она прописана). По сабжу хотелось бы ассоциативных массивов в стандартной либе. И switch/case на строки.
|
||||||
|
|||||||
| Sartorius |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1568 Регистрация: 18.7.2006 Где: Ivory tower Репутация: 8 Всего: 37 |
Можно функцию с переменным числом параметров... потом внутри передавать все это printf и еще макросы печатать |
|||
|
||||
| sergejzr |
|
|||
![]() Un salsero Профиль Группа: Админ Сообщений: 13285 Регистрация: 10.2.2004 Где: Германия г .Ганновер Репутация: 19 Всего: 360 |
Sartorius, не получится.
|
|||
|
||||
| likehood |
|
|||
|
666 ![]() ![]() Профиль Группа: Участник Сообщений: 536 Регистрация: 21.12.2005 Репутация: 8 Всего: 24 |
||||
|
||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
Мне бы очень хотелось получить аналог __property из BCB. Очень удобная штука. Да и реализация ее не так сложна.
Фиксированные типы тоже, имхо, очень нужны (не в ущерб стандартным). Путь даже доступ к ним можно получить подключив определенный заголовочный файл (необходимости жестко встраивать я не вижу). И хотелось бы чтобы они выглядели с явным указанием знаковости и разрядности (__uint32, __sint64 и т.п.). Стандарт на либы (в т.ч. и динамические) и ГУИ тоже нужен. Смысла выносить шаблоны в динамические либы не вижу, а вот стандарт на прекомпиляцию (или на использование его результатов) заголовочных файлов не помешал бы. Всеми руками за строки в switch/case. Текущая реализация RTTI мне не нравится (может не умею пользовтаься?). Не знаю как у других компиляторов, а у GCC имя объекта (как и виртуальные методы) определяется сразу перед вызовом его конструктора, т.е. если у меня Class2 потомок Class1, а в конструкторе Class1 есть сохранение имени класса, то сохранится Class1, хотя в итоге инициализируется Class2 - это очень напрягает. Было бы неплохо, чтобы сразу задавалось имя объекта, а не менялось перед каждым вызовом конструктора. Да и имя класса выдается какое-то кривое. Почему нельзя использовать для этого стандартные Namespace1 :: Namespace2 :: NamespaceN :: ... :: ClassName1 :: ClassName2 :: ... :: ClassNameN? Потом ведь проще отлаживать будет. Надеюсь, не только я RTTI использую исключительно для отладки? |
|||
|
||||
| Любитель |
|
||||||||
|
Программист-романтик ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3645 Регистрация: 21.5.2005 Где: Воронеж Репутация: 24 Всего: 92 |
Абсолютно не понял. Почему нельзя убрать первую строку и переименовать min_ в min? Компилер в состоянии выбрать конст- или нет версию.
Абсолютно не согласен с этим примером. Во-первых, даже в данном случае второое читается проще в силу его понятности. Во-вторых, это извращенское решение (по-моему). В данном случае лучше добавить шаблон, решающий, какой тип тебе нужен. С boost::enable_if и boost::Type_traits (замечу - решения, основанные только на шаблонах) подобные задачи решаются легко и (что немаловажно) естественно.
Пока что. Это ещё один из нужных к добавлению пунктов. Дальнейший код толком не читал, лишь просмотрел. Что могу сказать точно не в плюс макросам - большие макросы (коие я заметил в коде) очень плохо проверять на ошибки. Компилер выдаст ошибку на строку с его использованием (а макрос то многострочный), шаблоны же обрабатывает компилер, потому здесь всё нормально. Некоторые (подчеркну - некоторые) компилеры правда позволяет специальными опциями показывать код (и ссылки на ошибки по этому коду), полученный после издевательств препроцессора, но тем не менее это тяжело назвать удобным способом. Тем не менее, я не говорю выкинуть макросы лёгким движением руки. Я говорю предложить как можно больше типобезопасных, легкочитаемых альтернатив на уровне языка. std::map()? Упс, заметил, что про это уже сказали - неважно, повторюсь. Ну, конкретно это решение для плюсов вряд ли будет лучшим. Это всё-таки больше чистыми сями попахивает. Во-вторых, те вещи, которые требуют информации о строке, файле, текущей функции - пожалуй, тоже надо отнести к обязанностям препроцессора (по крайней мере я лучшего пока не вижу). Хотя всё таки это не очень хорошо. Тяжело засануть макрос, скажем в неймспейс Эффективность, к сожалению, будет потеряна, поэтому предпочтительней шаблонный код в статик-либах, тогда при сборке приложения компилер создаст нэтив-код. В принципе же, получаем для шаблонов некоторый промежуточный код, который при запуске приложения рантайм-либа должны развёртывать в нормальный. Точно пока это не представляю, но думаю, это возможно. Тем более не раз слышад подобные идеи от неглупых людей. Наконец таки проперти. Не поверишь - категорически против. В худшем случае на уровне библиотеки. ИМХО проперти противоречат существующим концепциям плюсов и лишь путают. В Яве прекрасно без ник обходятся - и правильно делают. Некоторые считают, что проперти понятней. В Delphi, с которым приходится работать в универе, скажем проперти есть. В итоге многие у нас в группе лишь путаются с пропертями, т. к. что это толком не знают, а считают их за нормальные переменные. В итоге пишут что-то такое:
Работать это конечно не будет. в итоге наши преподы рекомендуют (типа универсальное правило) заводить переменные, и присваиать им значение пропертей. А вконце (если надо!) - обратно. Скажем так:
Тяжело сказать, что мы что-то приобретаем... К тому же в стандартной библиотеки сложился уже другой подход. Вспомним, скажем функции классов потоков width, fill, precession. В концепции пропертёвых языков это явно должны были быть проперти. Я против этого. |
||||||||
|
|||||||||
| nickless |
|
|||
![]() Гентозавр ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2976 Регистрация: 29.8.2005 Где: Germany Репутация: 19 Всего: 181 |
А мне бы хотелось поддержки метаклассов и _нормальной_ поддержки указателей на методы классов (method pointers) как в delphi, это бы упростило создание и использование шаблонов типа factory, observer, итд.
-------------------- ![]() Real men don't use backups, they post their stuff on a public ftp server and let the rest of the world make copies - Linus Torvalds |
|||
|
||||
| Любитель |
|
|||
|
Программист-романтик ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3645 Регистрация: 21.5.2005 Где: Воронеж Репутация: 24 Всего: 92 |
Это я отношу к продвинутому RTTI. Хотя в полной мере - против. Слишком запарная реализация (по-моему). Согласен с получением метакласса, при указании некоторого базового класса (в Delphi, если не ошибаюсь class of основан на том, что TObject базовый для всех). А чем существующие ненормальны? |
|||
|
||||
| nickless |
|
|||
![]() Гентозавр ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2976 Регистрация: 29.8.2005 Где: Germany Репутация: 19 Всего: 181 |
Тем, что завязаны типом на один класс, т.е. если есть 2 не связанных наследствием класса А и B с методами int A::bla1() и int B::bla2 то нет возможности скажем сохранить указатели на bla1 и bla2 в массиве, типы разные. В delphi такие указатели используются для реализации событий (events), для С++ есть MOC (используется например в Qt), но реализация на уровне языка мне кажется удобнее. -------------------- ![]() Real men don't use backups, they post their stuff on a public ftp server and let the rest of the world make copies - Linus Torvalds |
|||
|
||||
| MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 52 Всего: 207 |
И получим очередной С# -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
| UnrealMan |
|
||||||||||||||||||||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 722 Регистрация: 30.3.2006 Репутация: 27 Всего: 32 |
Я же русским языком написал:
Попробуй-ка отправить своей min, например, 1 и 1.5 в качестве параметров. Сразу же получишь ошибку из-за неоднозначности (какой тип должен выбраться в качестве T: int или double? компилятор не может сам сделать выбор в пользу какого-либо варианта).
Ну, значит, у нас разное представление о понятности кода :-) boost пока не входит в стандарт, а это накладывает ограничение на его применимость. Есть ещё люди, которые boost не используют (и, разумеется, не устанавливают), и некоторым, вроде меня, с ними приходится считаться, а значит, возникает и необходимость разрабатывать свои собственные приёмы (либо остаётся кодить по-старинке).
Ну, не такие уж они и большие. Кроме того, вспомним, для чего создавались эти макросы. А создавались-то они для выхода на новый уровень абстракции. Следовательно, изначально можно создать конкретный прототип функции, класса или ещё чего-то (без макроса), протестировать его в действии, а затем уже переделать данное конкретное воплощение в абстрактную форму. Шансы допустить какие-то трудновыявляемые ошибки при этом невелики (ну если только не в полуспящем состоянии кодить). Пусть, например, требуется решить задачу: установить, есть ли в заданном классе метод с заданными: именем, типами возращаемого значения и параметров (метод нешаблонный). Одна из возможных реализаций для решения задачи в отношении конкретного метода swap такова:
Сразу же бросается в глаза следующий факт: название функции намертво привязано к нашему классу HasSwap. Мы можем создавать шаблоны, где параметры – классы, но имена функций в качестве параметров шаблона мы передавать не можем. Поэтому в общем в виде поставленная задача не имеет решения... без макросов. Да-да, вместо того чтобы для каждого имени метода создавать вручную собственный класс по одной и той же схеме, можно один раз написать общие макросы
и далее задействовать их. Например, создание и использование класса вроде HasSwap будет выглядеть примерно следующим образом:
Трудно понять, что ты хочешь сказать. Ведь это
не я же сочинил? Может, если бы я использовал boost, то думал бы примерно так же, но разрабатывая собственную библиотеку (частично как альтернативу boost, которую с легкостью можно перекинуть на другой комп вместе с проектом), я убедился в том, что такое суждение весьма далеко от истины. После того как поработаешь с абстракциями высокого уровня, читать в некоторых умных книжках рекомендации вроде «не используйте макросы, а используйте шаблоны вместо макросов» просто смешно – создаётся впечатление, что автору по части обобщённого программирования ничего сложнее
писать больше не приходилось. |
||||||||||||||||||||||
|
|||||||||||||||||||||||
| Любитель |
|
|||
|
Программист-романтик ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3645 Регистрация: 21.5.2005 Где: Воронеж Репутация: 24 Всего: 92 |
UnrealMan, во-первых, всё-таки, если хочется поспорить на тему "Макросы: быть или не быть" - я не против, но маленькая просьба (если действительно хочется) - пускай это будет отдельная тема. Возможно, было бы интересно. Пока же отвечу на некоторые моменты твоего поста:
А ты в своём примере попробуй - сделает ли он выбор? type_traits точно войдёт, enable_if - очень вероятно. Проектирование наизнанку?
Оператор typeof, который на 90% войдёт в новый стандарт решает это гораздо элегантней + типосейфити и прочее. Речь про компатибилити. Да, подумав, понял, что для шаблонов в динамик-либах я загнался (в первую очередь из-за сложности их взаимодействия с обычными шаблонами). Но вот в статик-либах - обязательно. Добавлено @ 18:03 С точки зрения C++ (и моей тоже) подобное поведение будет нелогично. Если нужно - создай абстрактный базовый класс, не забывай про множественное наследование. Это гораздо практичнее. Насчёт дельфийских ивентов - с системой сигнал/слотов они и близко не лежали. Вспомни, хотя бы, что слотов можно законектить несколько на один сигнал. В Дельфи (насколько я знаю) такого невозможно по определению (архитектура такая). И ещё - советую посмотреть в сторону Boost.Signal (сигнал/слоты, реализованные с помощью языковых возможностей). Достаточно перспективно. |
|||
|
||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |