Здравствуйте, VladD2, Вы писали:
VD>Нет. Сигналы как раз и есть эмуляция делегатов. Своеобразная, но эмуляция.
Да начерта их эмулировать? Это самоцель что ли? Главное — обеспечить удобный простой и лаконичный типизированный оо колбек, а уж как это обеспечивать второй вопрос. Делегаты — неплохое приближение к идеалу, но совершенно точно еще не идеал. С введением к примеру анонимных методов станет все еще интереснее.
VD>Можно взразить, но ведь на сегодня эти гору за частую написаны! Да. Но во что это выливается? На любой плевок нужно создать целый отдельный класс! Это приводить к неимоверным затратам времени на компиляцию. Один из наших проектов компилируется 25 минут на Атлон 1400! И это как раз в основном из-за шаблонов. Причем наши шаблоны бустовским не чета.
Ну тут даже без шаблонов проблем достаточно. Небольшой TreeGridBase компилируется в разы дольше чем весь остальной янус, и это при том что компилер шарпа 1 версии, а плюсов 7.
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, VladD2, Вы писали:
VD>>Да я вроде и без него в С++ разбирался. WH>Я тоже так думал...
WH>Из предисловия Скотта Мейерса WH>
WH>Если, прочитав материал, посвященный спискам типов, вы не свалились со стула, значит, вы сидели на полу.
Угу... я его сейчас читаю... смотрю на мир безумными глазами... Отхожу плохо...
Книгу нужно зарегестрить как психотропное средство...
Здравствуйте, VladD2, Вы писали:
VD>Так вот в бусте создана целая гора кода, чтобы сэмулировать такое простое решение. Если в С++ наплевать на типобезопастность, но написать такую фитюльку ничего не стоит.
Фитюлька написана с соблюдением типобезопасности. Если хочешь показать reinterpret_cast или static_cast на потомка в реализации сигналов — дерзай, исходники доступны. Я знаю одно такое место — static_cast внутри any_cast, но он сделан для увеличения производительности (как, скажем, некоторые unsafe методы класса String) и может быть безболезненно заменен на dynamic_cast.
VD>Это форменное удаление гланд через анус автогеном. И очередная демострация затыкания ущербности языка средствами использования шаблонов не по назначению.
Да. Шаблоны задумывались для тех же целей, что и generics сейчас, но оказалось, что на них можно сделать гораздо больше. Вообще c++ — омерзительный язык, и я, если мне дадут такую возможность, вместо порта ado.net на плюсы лучше бы писал что-нибудь на c#, смирив гордыню и наплевав на шаблоны, дожидаясь generics. Но 700 строк реализации шести вложенных в System.Windows.Forms.ListView коллекций не дали мне сегодня спать до трех часов ночи...
VD>Так вот в бусте создана целая гора кода, чтобы сэмулировать такое простое решение.
Кстати, раскрою секрет: на шаблонах невозможно сделать аналог делегатов с произвольным числом параметров. Для каждого n от 0 до 10 есть шаблон делегата с n параметрами, а потом они приведены в общий вид с помощью макросов
Здравствуйте, AndrewVK, Вы писали:
AVK>Что значит из стандартных кирпичиков? Ты имеешь ввиду подключение реализаций? Пример того как это реализовать я приводил в форуме по дотнету.
Вмешаюсь, по поводу Александреску.
Да, код кажется ужасным. Но этот код _не_ предназначен для того, чтобы его читали. Это код _не_ для повседневного использования.
Александреску в своей книге описывает библиотеку, описание которой надо прочитать, а потом, поняв основные ижеи, пользоваться, дополнять etc.
Код же использующий эту библиотеку, наоборот, очень читабелен, да и вообще, основной целью библиотеки Loki является замена громоздкого кода на лаконичный и легкочитаемый.
Здравствуйте, Plutonia Experiment, Вы писали:
PE>Здравствуйте, WolfHound, Вы писали:
WH>>Здравствуйте, AndrewVK, Вы писали:
AVK>>>Мне чего, заняться нечем разбираться в коде, да потом еще и реализовывать на шарпе. Нужно будет, реализую. WH>>А что тут разбираться это просто пример того как можно написать несколько стандартных кирпичиков, а потом из них собирать классы. WH>>А как на C# можно из стандартных кирпичиков собирать классы?
PE>И ты столько кода нагнал, чтобы показать всю прелесть множественного наследования ?
имеется ввиду не наследование, а сборка класса на этапе компиляции
Ooops! не получилось, а в редакторе все так мило выглядело
попробуем так:
Holder<int> ----------------\
Holder<string> --------------|---WidgetInfo
Holder<Widget> -------------/
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, mihailik, Вы писали:
VD>C1<class Base> VD>{ VD> void Method1() VD> { VD> Base * pBase = static_cast<Base*>(this); // так яснее намерения VD> int i = pBase->SomeUniversalWork(); VD> } VD>С2 : public C1<C2> VD>{ VD> int SomeUniversalWork() VD> { VD> } VD>}; VD>С3 : public C1<C2> VD>{ VD> int SomeUniversalWork() VD> { VD> } VD>};
Этот код нетипобезопасен — если написать C2: public C1<C3> или вызвать C1::Method1 из конструктора C1, то возникнет неопределенное поведение. С использованием generics аналогичный код будет выглядеть примерно так:
interface ISomeUniversalWork
{
int SomeUniversalWork();
};
class C1<T> where T : ISomeUniversalWork {
public void Method1() {
int i = ((T)this).SomeUniversalWork();
}
}
class C2 : C1<C2>, ISomeUniversalWork
{
int ISomeUniversalWork.SomeUniversalWork() {
return 0;
}
};
При текущей реализации generics приведение (T)this будет съедать весь эффект от невиртуальности, но в принципе никто не мешает будущей версии компилятора сынлайнить все это до нужного состояния.
Здравствуйте, Nose, Вы писали:
N>Да, код кажется ужасным. Но этот код _не_ предназначен для того, чтобы его читали.
Любой код должен быть предназначен для того чтобы его читали, кроме кода, время жизни которого 1-2 дня. Можешь напечатать на большом листе и повесить на стену.
И дальше получается та же одна строка.
IT>Я конечно понимаю, что поступаю не совсем честно, в C++ нет нормального RTTI и видимо никогда не будет, но я хочу сказать, что в 99.99% задач твои знания шаблонов вряд ли пригодятся. А если бы ты и попытался их где-либо применить, то работая, к примеру, в моей команде, я тебе просто элементарно запретил бы это делать.
Не надо путать написание шаблонов и их использование. Запрещать использовать vector, string, map, sort при работе на c++ — очень странное решение.
IT>Для меня эталоном программы уже давно является не виртуозное владение указателями, свитчами и шаблонами, а ясный и понятный, хорошо оформленный и откомментированный код. Впрочем, может это я просто старею...
Глядя на наши компилящиеся час на p4/1.8 полмиллиона строк, я регулярно говорю окружающим: ну их нафиг, эти шаблоны и множественное наследование, если для того, чтобы пользователи могли использовать наши классы на своем (опять кривом) прикладном языке, надо писать километры таких макросов. Не слушают.
Здравствуйте, IT, Вы писали:
IT>А вот ответь мне, мил человек, сможешь ли ты на C++ (не MC++) сделать из чего-то типа первого примера, что-то типа второго?
Первый легко. ADO.
Правда имена типов страшнее, но болие типобезопасно.
IT>А теперь добавим немного рефлекшина внутрь и получим:
Мда... печальное зрелище... без пузыря не разберёшся.
Это сделает их как раз только запутаннее и непонятнее и будем им грошь цена, после того как какой-нибудь студент, идущий за тобой, не поняв что там происходит, просто перепишет твой код на нормальный понятный язык. И будет, между прочим, прав.
И что теперь говорить что рефлекшен фигня? Если в .NET будут шаблоны уровня С++ и множественное наследование я сразу забью на С++.
К стати когда студент поймет что на "простом" и "понятном" языке придется писать в 10 раз больше и не будет дураком он пойдет читать Александреску.
IT>В твоём примере трудно понять вообще для чего он нужен,
Обыкновенная сборка классов из кирпичиков причем один кирпичик может изменить реализацию другого причем даст компилятору кучу информации при помощи которой он может инлайнить методы из карпичика A в методе кирпичика B. Воспользовавшись этим я показал как можно писать кирпичи с учетом многопоточности и использовать в однопоточном приложении так что компилятор убьет весь код синхронизации.
IT>в моём надеюсь тебе не просто будет всё понятно, а даже тривиально с первого взгляда.
Первый да второй нет(вернее догадаться по контексту могу, а повторить...даже на С#... ).
Таже проблема что и у тебя с моим кодом плохое знание матчасти.
IT>И прибегать к услугам Александреску чтобы понять этот код не надо.
А к чьим можно прибегнуть для того чтобы понять пример с рефлекшеном?(В принципе я понимаю как это работает но хочется по подробней)
IT>Я конечно понимаю, что поступаю не совсем честно,
Я тоже IT>в C++ нет нормального RTTI и видимо никогда не будет, но я хочу сказать,
В C# не шаблонов и судя по слухам нормальных не будет.
К стати тоже судя по слухам рефлекшен в С++ хотят делать. IT>что в 99.99% задач твои знания шаблонов вряд ли пригодятся.
А что ты постоянно используешь рефлекшен? IT>А если бы ты и попытался их где-либо применить, то работая, к примеру, в моей команде, я тебе просто элементарно запретил бы это делать.
А в своей конторе я написал фрейморк на шаблонах такой что получилось практически нормальное компонентное программирование. И ни кто не назвал меня извращенцем ибо по сравнению с тем что было до меня все много проще, понятней и удобней.
IT>Для меня эталоном программы уже давно является не виртуозное владение указателями, свитчами и шаблонами, а ясный и понятный, хорошо оформленный и откомментированный код. Впрочем, может это я просто старею...
А у меня клиетский код ясный, понятный, хорошо оформленный и откоментированый. Библиотека к стати тоже правда только после прочтения Александреску.
Ни какой адресной арифметики(сразу по бошке), ни каких свитчей, а шаблоны явно используются толко в смартпоинтерах, при кастовании и создании обьектов(смартпоинтеры не избежно, а кастование и создание я решил что лучше указать явно нужнай тип)
Создание обьекта по имени класса прочитаному из какого либо конфига. Причем реализация обьекта можнет находится в либой из оформлкнных по (очень простым) правилам длл(ессно прицепленных к приложению).
Ref<I_Sensor> sensor=CreateObject<I_Sensor>(sensorClassName);
ENFORCE(sensor, X_InvalidClassName)("Class Name =\"")(sensorClassName)("\"");//Исключение будет автоматом записано в лог
sensor->Name=sensorName;//Что грузить
sensor->DataBase=dataBase;//От куда грузить
ENFORCE(sensor->Load(), X_InvalidSensorName)("Class Name =\"")(sensorClassName)("\"; Sensor name =\"")(sensorName)("\"");
// Messge : Class Name ="MyCoolSensorClass"; Sensor name ="MyCoolSensor"
//См ниже
Блин ну и аппликуха у меня исключений не дождешся проще всего форсировать это
Здравствуйте, AndrewVK, Вы писали:
AVK>Нету ее у меня. Поищи в поиске.
Не получилось. Попробуй пару ключевых слов привести.
AVK>При желании в том подходе, пример которого приведен можно наворотить такие извратства, что плюсам и не снились, только вот нафик никому это не нужно.
Сначала я посмотрю, а потом поговорим.
... << RSDN@Home 1.1 alpha 1 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, VladD2, Вы писали:
VD>А кто это говорил? Тебе говорят, что он тяжел и во многом отстал от жизни. Цитату можешь привести? Re[9]: Будущее C#
Здравствуйте, WolfHound, Вы писали:
WH>Правда имена типов страшнее, но болие типобезопасно.
Ты фишку не понял — первый пример это то как можно реализовать и в С++. Вся закавыка именно во втором.
IT>>А теперь добавим немного рефлекшина внутрь и получим: WH>
WH>Мда... печальное зрелище... без пузыря не разберёшся.
Действительно, непонятно нифига
WH>И что теперь говорить что рефлекшен фигня? Если в .NET будут шаблоны уровня С++
Что это за уровень такой? А шаблоны будут, вполне достаточного для дотнета уровня.
WH>и множественное наследование
Вот без этого точно можно прожить.
IT>>в моём надеюсь тебе не просто будет всё понятно, а даже тривиально с первого взгляда. WH>Первый да второй нет(вернее догадаться по контексту могу, а повторить...даже на С#... ). WH>Таже проблема что и у тебя с моим кодом плохое знание матчасти.
Я подобный функционал сделал примерно через месяц после того как впервые увидел дотнет. И знание матчасти тут не при чем.
WH>А что ты постоянно используешь рефлекшен?
Я например весьма часто.
WH>Создание обьекта по имени класса прочитаному из какого либо конфига. Причем реализация обьекта можнет находится в либой из оформлкнных по (очень простым) правилам длл(ессно прицепленных к приложению). WH>
WH> Ref<I_Sensor> sensor=CreateObject<I_Sensor>(sensorClassName);
WH> ENFORCE(sensor, X_InvalidClassName)("Class Name =\"")(sensorClassName)("\"");//Исключение будет автоматом записано в лог
WH> sensor->Name=sensorName;//Что грузить
WH> sensor->DataBase=dataBase;//От куда грузить
WH> ENFORCE(sensor->Load(), X_InvalidSensorName)("Class Name =\"")(sensorClassName)("\"; Sensor name =\"")(sensorName)("\"");
WH> // Messge : Class Name ="MyCoolSensorClass"; Sensor name ="MyCoolSensor"
WH> //См ниже
WH>
Здравствуйте, AndrewVK, Вы писали:
AVK>Ссылку на whitepaper с описанием изменений языка в .NET 2.0 давали неоднократно, различиям темплейтов и дженериков там посвящена отдельная глава.
Там практически ничего не сказано. По крайней мере для серьезного суждения точно ничего нет. Так что ты хоть одно координальное отличие приведи. Я вот только заметил, что не будет параметризованных функций. Прискорбно конечно, но не смертельно.
AVK>Можно, вот только результатом этого как раз и являются вопли о неправильности шарпа.
Не надо песен. Шарп и в правду не совершенен. И большинство воплей по делу, если конечно это не простое фанатство.
... << RSDN@Home 1.1 beta 1 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, VladD2, Вы писали:
VD>>Все до одной. Другой вопрос что этот менеджед-код не будет совместим с CLS.
AVK>Да? И ты берешься сделать к примеру класс с МН менеджед?
Легко. Компилируются даже шаблонные навароты ATL-я.
AVK> Не путай пожалуйста IL-код и-managed код.
Не путаю. IL == managed. То о чем говоришь ты называется "CLS-совместимый".
AVK>Когда ты объявляешь класс gc то очень многие фичи становяться недоступны.
__gc необязателен для того чтобы код был менеджед. __gc коворит компилятору, что объект должен размещаться в менеджед хипе.
... << RSDN@Home 1.1 beta 1 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Andir, Вы писали:
A>Вот что-что а я бы посоветовал Владу глянуть всё таки эту книжку ... Там есть над чем посмеяться, самые очевидные вещи решаются такими уродскими способами (реализация, а не задумка ) и всё это подаётся под таким соусом, как откровение ...
К сожалению я все это видел воочию. Многих программистов так и тянет сделать что-нибудь через ухо. А на счет глянуть... поподет в руки обязательно гляну. Вот только точно не буду искать ее с высунутым языком. С++ для меня теперь средство решений проблем которые нужно решать на уровне битов.
A>Правда до главы со списками я ещё не дошёл, но эта книжка прекрасный повод для критики С++ ... Язык морально устаревает и люди вроде Александреску пытаются показать, что на С++ можно делать и кое-что новое, что в том же Шарпе делается просто и лаконично ...
Во-во. Это я из Александреску вижу. Причем мне нравится С++, но мне так же нарвится компонентный подход и хочется решать стоящие задачи просто и элегантно. К сожалению, С++ далек от простоты и элегнтности. Ну, а компонентность в нем отсуствует полностью.
A>А самое главное, что важно для программиста это ну очень трудное чтение исходников, потому что оно неочевидное. Простые вещи скрываются под таким набором конструкций в которых в жисть эту вещь не узнаешь. В голову приходит только одна аналогия (особенно связанная с форматированием исходников — когда темплейтные определения разносят по строчкам) — ассемблер нашего века.
Именно.
... << RSDN@Home 1.1 beta 1 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, m.a.g., Вы писали:
MAG>Это коллекции типов.
И это приводится в качестве аргумента в споре с Шарпом использующим самый мощьный на сегодня механизм предоставления информации о типах (рефлекшон)?
MAG>Причем работа с ними идет во время компиляции.
Дык информация о типах нужна то обычно в рантайме, а вот тут у плюсов идеологический калапс. Его авторы просто не думали о рантайме при проектировании языка.
... << RSDN@Home 1.1 beta 1 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.