Здравствуйте, Sergey, Вы писали:
S>CreatorCray пишет:
>> S>а вот с какой целью изготовили похожую на нее WTL и, особенно, почему >> S>люди ей пользуются — для меня загадка. >> WTL ИМХО больше на MFC похожа.
S>Ну не знаю. Внутри она устроена как оконная часть ATL, из которой S>собственно и сделана — с чего бы ей быть похожей на MFC? DDX разве что S>приделали MFC-образный.
>> Пользуются потому, что удобнее чем MFC. >> Не требует ничего тащить с программой — никаких dependencies.
S>Что тащить ничего не надо — это замечательно. Но вот что она S>обеспечивает такого, чего нет в винапи? Докинг там скажем или что-нибудь S>подобное wxSizer? Или GDI объекты умеет правильно уничтожать, как та же S>wxWidgets? Или куча стронних контролов под нее есть, как под MFC? S>IMHO, без разницы — на голом винапи писать или с WTL.
Вот разница как раз есть. Лично для меня WTL — это как очень удобная обертка для WinAPI. Некоторые библиотеки представляют обертку над WinAPI, скрывая тонкости программирования на голой платформе, а вот WTL упрощает программирование на этой платформе.
Так что ИМХО — WTL лишь обертка над WinAPI(именно на том уровне, что надо его знать, что бы писать на WTL).
Лично мне все время мешает то, что в С++ нет понятия "просто имя", которое можно было бы свободно передавать в шаблоны и уже при инстанцировании бы компилятор разбирался, что я туда засунул — функцию, класс, шаблон, перегруженную функцию, объект...
Это из того, что почти повседневно мешает в коде, поэтому сразу приходит на ум.
А из общего:
1. Препроцессор, убогий и отвязанный от С++ (нет доступа ни к синтаксису, ни к системе типов, ни к чему). Как надо — см. макросы в Немерле.
2. Подключение хедеров через препроцессор. Решено, наверное, почти везде текстовым включением сейчас разве что скриптовые языки только пользуются типа bash/make. А из этого следует безумное время компиляции и геморрой с созданием нормальной IDE.
3. Нет нормальных IDE, которые понимали бы все, что умеет С++ (т.е. препроцессор, шаблоны, перегрузку и т.д.). Решено в Java и C#.
4. Стилистический разнобой в имеющихся библиотеках (причем в каждой все реализовано по-своему). Решено в централизованных языках типа Java и C#. Сейчас решается посредством STL и буста, но как-то очень неспешно (хотя некоторые библиотеки уже предоставили STL-совместимые интерфейсы доступа).
5. Отсутствие нормальной мета-информации во время компиляции (a.k.a API компилятора, доступный из самой программы, с информацией обо всем — о типах, объектах, функциях, свойствах всего этого, в общем, все, что знает о программе сам компилятор, должно быть доступно и самой программе, причем желательно не только read-only). Из-за этого приходится извращаться с шаблонами, а все в систему типов ведь не запихнешь (например, генерацию именованных членов), не говоря уже об удобстве. В каком-то смысле связано с п.1, ну и решение там же
Да! Язык сложный.
И не каждый скоро освоит его, я сам еще иногда натыкаюсь на интересные приемы, по большей части касающихся шаблонного программирования.
Но это скорее + чем -.
a = [ ... ]
b = []
c = []
a.each do |item|
if item > 0
b << item
else
c << item
end
end
R>
vector_t a, b, c;
BOOST_FOREACH(SOME_TYPE item, a)
(item > 0 ? b : c).push_back(item);
Я не знаю Ruby и (надеюсь) знаю C++, тем не менее пример на Ruby прочитал быстрее чем пример на C++, несмотря на то что последний читал после первого и соответственно уже знал, о чем речь. Как будто вовсе не Ruby, а C++ был изобретен человеком какой-то другой, далекой культуры; японцем каким-нибудь что ли...
PS. Наверное и на Ruby при желании можно заменить if-else-end на что-нибудь вроде ?:.
Здравствуйте, eao197, Вы писали:
E>Здравствуйте, remark, Вы писали:
R>>Что Вам мешает в С++?
Отсутствие безопасного режима...
а разве msvc8, 9 не позволяет генерировать CLR код? Вроде quake 2 портировали полностью — и работает полностью на .NET (сорри если ошибся — честно говоря в код портированной кваки не лазил, однако сомневаюсь что ее переписывали с C на C#).
1. Допустимость переменных с одинаковыми именами во вложенных областях видимости. Даже варнинги на четвертом уровне не выдает, зараза.
int i = 0;
{
int i = 0;
... код ...
обратимся к i. Угадай с трех раз к какому при быстром просмотре кода :(
}
2. Отсутствие полиморфизма времени компиляции в макросах. В С99 конечно вариадики ввели, но все равно не айс
3. Невозможность вложенного препроцессора.
4. Возврат функцией только одного значения. Бесконечные ссылочные и указательные аргументы — лишний код . Возврат классов не панацея
Здравствуйте, NikeByNike, Вы писали:
NBN>Здравствуйте, Alexander G, Вы писали:
RO>>>Объясни, пожалуйста, что именно могут делегаты и не могут лямбда-функции и std::function. AG>>std::function — не на уровне языка, поэтому не отвечают на ответ
NBN>Всётаки — зачем нужны делегаты на уровне языка? Они вообще-то не попадают в концепцию С++ой лаконичности.
Хотя бы для удобства отладки, чтобы можно было проваливаться сразу в слот.
Видели размер стека между точкой вызова сигнала и вызовом подписанной функции ?
Не говоря уже о том, что реализация в том же boost глючная — там автоотписка не работает.
Здравствуйте, Alexander G, Вы писали:
AG>Я начинал с Delphi, поэтому что мешает:
AG>1. Отуствие finally. Да, я в курсе про RAII, смарт-поинтеры в т.ч. с кастомными деаллокаторами и скоп гарды. Но меня не устраивает навязывание ООП здесь. Выходит, что С++ не поддершивает стиль старого дорбого С (хотя вроде как пытается поддерживать и С и ООП и даже ФП). Сюда же то, что деструктор не вызовется для недоделаных объектов (в Delphi — вызовется), что требует не только помещать ресурсы в классы, но и помещать кажды ресурс в свой класс. If I hear the phrase``everything is an object'' once more, I think I will scream.
Одна из причин "невызова" деструктора в том, что в плюсах объект никак не инициализирован на момент вызова конструктора.
В Delphi производится инициализация по умолчанию нулями до вызова конструктора, потому в деструкторе вполне можно писать x.Free для всех динамически аллоцированных членов класса.
В плюсах же, если даже деструктор и вызывался бы, все равно было бы не понятно что там делать.
Ибо часть объектов инициализирована, а часть содержит мусор. Но кто есть кто — не понять.
Потому даются лишь гарантии для списка инициализации, а в теле конструктора контроль можно производить вручную.
AG>2. Наследие С. Выражается в недостаточной типизации. Пример: '\0' NULL и 0 — совместимы, причём последние 2 вообще одно и то же. В паскале nil 0 и #0 компилятор не даст попутать if (p) p = 0 /* я пропустил * перед p но компилятор не проглотил, т.к. nil и 0 одно и то же */. Также в С путают указатель с массивом. И выражение с операцией. Возможностью написать короче пользоваться не приходится, т.к. требуется написать понятнее, но ошибки типа if (a = b) сделать всё равно можно.
+
AG>3. Я не могу клепать формы на WTL так быстро, как это получалось в Delphi
R>Что Вам мешает в С++?
R>1. Мешать это должно регулярно. Т.к. если это мешает эпизодически, например, раз в год, то это не интересно, т.к. раз в год можно и потерпеть, и на общей эффективности разработки это не сказывается. R>2. Это должно быть решено в других промышленных языках. Т.к. если это не решено хотя бы в одном другом промышленном языке, то это не интересно, т.к. это не проблема С++, а просто общая проблема. Если не очевидно, то желательно указывать языки, в которых это решено.
Первое, что приходит в голову -- работа с памятью. Указатели, преобразование указателей, выделение и освобождение памяти... Ускорение разработки при переходе на C# (к примеру для GUI) из-за этого поразительное.
Еще, пожалуй, обилие диалектов. Когда при обновлении Visual Studio перестает компилироваться код, это очень огорчает. Думаю, ни в одном другом языке эта проблема не цветет таким махровым цветом.
Здравствуйте, s.ts, Вы писали:
AG>>Сюда же то, что деструктор не вызовется для недоделаных объектов (в Delphi — вызовется), что требует не только помещать ресурсы в классы, но и помещать кажды ресурс в свой класс.
А как, по-твоему, деструктор мог бы вызываться для объекта, который никогда не существовал?!
Здравствуйте, remark, Вы писали:
R>Что Вам мешает в С++?
Не доконца продуманная, на мой взляд, поддержка исключений.
Хотелось бы, например, такую как в Jave. Было бы не плохо, если бы компилятор мог сказать: "Вот это я компилировать не буду, так как у вас тут исключение не обрабатывается". Ато приходится лазить по исходникам и смотреть, кто какие исключения генерирует, какие либы используются и что они выплёвывают.
Здравствуйте, Pasternak, Вы писали:
P>Не доконца продуманная, на мой взляд, поддержка исключений. P>Хотелось бы, например, такую как в Jave. Было бы не плохо, если бы компилятор мог сказать: "Вот это я компилировать не буду, так как у вас тут исключение не обрабатывается". Ато приходится лазить по исходникам и смотреть, кто какие исключения генерирует, какие либы используются и что они выплёвывают.
Это мешало бы вызывать из C-функций C++-функции (переданные, например, в качестве callback'а).
Здравствуйте, Alxndr, Вы писали:
A>Здравствуйте, Pasternak, Вы писали:
P>>Не доконца продуманная, на мой взляд, поддержка исключений. P>>Хотелось бы, например, такую как в Jave. Было бы не плохо, если бы компилятор мог сказать: "Вот это я компилировать не буду, так как у вас тут исключение не обрабатывается". Ато приходится лазить по исходникам и смотреть, кто какие исключения генерирует, какие либы используются и что они выплёвывают.
A>Это мешало бы вызывать из C-функций C++-функции (переданные, например, в качестве callback'а).
Вообще выпускать какие-либо исключения за пределы функций callback-ов мне кажется не очень хорошо. Тот кто вызывает эту С-функцию понятия не имеет какие исключения могут генерироваться. Лучшее, что он может сделать это перехватить всё и сообщить об ошибке.
Но и в этом случае можно было бы решить вопрос генерации исключений в callback-ах например, через тип указателя на функцию.
Например как то так (первое что пришло в голову):
Здравствуйте, Pasternak, Вы писали:
P>Но и в этом случае можно было бы решить вопрос генерации исключений в callback-ах например, через тип указателя на функцию. P>Например как то так (первое что пришло в голову):
P>
Здравствуйте, StevenIvanov, Вы писали:
SI>а разве msvc8, 9 не позволяет генерировать CLR код? Вроде quake 2 портировали полностью — и работает полностью на .NET (сорри если ошибся — честно говоря в код портированной кваки не лазил, однако сомневаюсь что ее переписывали с C на C#).
Насколько я понимаю, для CLR нужно писать на C++/CLI, а это несколько иной язык.
Да и MS и Win ведь дело не ограничивается. Люди годами пишут исключительно под Unix и даже не имеют необходимости портироваться под Windows.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, Pasternak, Вы писали:
P>Не доконца продуманная, на мой взляд, поддержка исключений. P>Хотелось бы, например, такую как в Jave. Было бы не плохо, если бы компилятор мог сказать: "Вот это я компилировать не буду, так как у вас тут исключение не обрабатывается". Ато приходится лазить по исходникам и смотреть, кто какие исключения генерирует, какие либы используются и что они выплёвывают.
RO>где один плагин пишет в файл, другой — в БД, третий — еще куда-нибудь.
RO>Как здесь определить функцию Document::save(Plugin &) throw(а вот что здесь?)?
В общем случае — что угодно, а в данном случае что-то типа DocumentSaveError. Пускай плагины смотрят за тем, что они выбрасывают и подстраиваются под требования функции Document::save. В Jave такая проблема ведь как-то решается.
RO>По-моему, checked exceptions à la Java мешают расширять программы в будущем.
Возможно, но хотелось бы хотя-бы ворнинги какие-то, если эксепшн пропущен.