D vs C++
    , почти сурковская пропаганда: не пора ли C++ потихоньку готовиться к пенсии?
  ![]()  | 
Наши проекты:
 Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту  | 
|
| ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS | 
| [216.73.216.5] | 
 
 | 
		
  | 
    Правила раздела:
  | Страницы: (56) « Первая ... 12 13 [14] 15 16 ... 55 56 ( Перейти к последнему сообщению ) | 
    D vs C++
    , почти сурковская пропаганда: не пора ли C++ потихоньку готовиться к пенсии?
  | 
         
         
         
          
           Сообщ.
           #196
          
          , 
          
         
         
        
       | 
    |
| 
         | 
      
         Цитата korvin @  Во-первых не пара и не тройка, попробуйте что-ли. Во-вторых, любой синтаксический сахар кому-то нравится, а кому-то нет. Это всего лишь один из вариантов применения строковых литералов в качестве параметра шаблона. 	 На пару-тройку символов? Вообще погоды не делает. От каррирования и то больше разницы.   | 
    
| 
         
         
         
          
           Сообщ.
           #197
          
          , 
          
         
         
        
       | 
    |
| 
         | 
      
         Цитата applegame @  Это всего-лишь один из вариантов применения строковых литералов в качестве параметра шаблона. Сам сей факт не вызывает отторжения. А вот зачем запихивать в строку код - непонятно. Пример хоть покажите радикальной экономии символов.  | 
    
| 
         
         
         
          
           Сообщ.
           #198
          
          , 
          
         
         
        
       | 
    |
| 
         | 
      
         Цитата applegame @  Во-первых не пара и не тройка, попробуйте что-ли. Ровно два: ![]() ![]() find!"a.key == b"(foo, 1) find!(a => a.key == 1)(foo) Ведь без строк нам не нужен параметр b. А если бы не !, то вообще один символ.  | 
    
| 
         
         
         
          
           Сообщ.
           #199
          
          , 
          
         
         
        
       | 
    |
| 
         | 
      
          Впрочем, что-то мы увлеклись строковыми предикатами, пример я привел, чтобы разъяснить как вообще работает компиляция строк, в качестве пояснения к вопросу 
        
      "Строковый" предикат - это простая строка. Предикатом его делает функция find, поэтому, естественно, никаких захватов контекстов нет. Для захвата контекста - есть обычные лямбды.  | 
    
| 
         
         
         
          
           Сообщ.
           #200
          
          , 
          
         
         
        
       | 
    |
| 
         | 
      
         Цитата korvin @  Если юзать предикат с одним параметром, то и в "строковом" варианте можно убрать b (пять символов Ведь без строк нам ненужен параметр b.   ):![]() ![]() find!"a.key == 1"(foo) find!(a => a.key == 1)(foo) правда лямбда может захватить внешний контекст, а строка нет: ![]() ![]() int b = 1; find!"a.key == b"(foo);     // ошибка find!(a => a.key == b)(foo) // все ок Доступен, опять же синтаксический сахар, который, лично мне нравится: ![]() ![]() foo.find!"a.key == b"; Добавлено На сягодня я заканчиваю. Завтра расскажу о других, не менее интересных для обсуждения, возможностей D.   	  | 
    
| 
         
         
         
          
           Сообщ.
           #201
          
          , 
          
         
         
        
       | 
    |
| 
         | 
      
         Цитата applegame @  Доступен, опять же синтаксический сахар, который, лично мне нравится: Смотри сахарный диабет не заработай.  | 
    
| 
         
         
         
          
           Сообщ.
           #202
          
          , 
          
         
         
        
       | 
    |
| 
         | 
      
         Цитата applegame @  Доступен, опять же синтаксический сахар, который, лично мне нравится Пока такие "киллер фичи" будут продвигаться новыми языками, у C++ обеспеченное будущее.  | 
    
| 
         
         
         
          
           Сообщ.
           #203
          
          , 
          
         
         
        
       | 
    |
| 
         | 
      
          Я что-то не пойму, об чём холивар. Если не ошибаюсь, поправьте, если не если, Александреску задумал D не как убийцу C++, а как язык с ориентацией на парадигму обобщённого программирования и без груза обратной совместимости с чем бы то ни было, а значит и лишённого набившего в C++ оскомину. Так что по определению везде, где требуется ниша мета- и К°, D наверняка предложит сырец покрасивше, где требуется "железный" уровень абстракции, он сольёт, в остальных случаях будет пофик. Остаётся только вопрос практичности результата там, где D якобы превосходит. Собственно и всё. А вы тут какую-то хрень обсуждаете. 
        
      Возвращаясь к интерфейсам. Интерфейсы в Плюсах всю жизнь прекрасно эмулировались виртуальными базовыми абстрактными классами. Невиртуальный базовый класс, неважно, абстрактный или нет, однозначно не используется как интерфейс. Всё это превосходно дружит с множественным наследованием реализаций. Какие ещё могут быть тут вопросы? Разве что к D. applegame, приведи пример простенького сериализатора на D. Кто не ходит в Общие Плюсы, вот ссылка на предмет измерения длины. Для понять, откуда ноги, там есть первая страничка темы. Интересно посмотреть на D-код в контексте, где он должен быть на коне.  | 
    
| 
         
         
         
          
           Сообщ.
           #204
          
          , 
          
         
         
        
       | 
    |
| 
         | 
      
         Цитата Qraizer @  Претензия к D, что у него якобы интерфейсы реализованы не совсем так как привычно (ссылаются на прочие языки с интерфейсами). А именно с одной особенностью. Тут не важно виртуальный базовый класс или нет. Виртуальность ничего не меняет:Возвращаясь к интерфейсам. Интерфейсы в Плюсах всю жизнь прекрасно эмулировались виртуальными базовыми абстрактными классами. Невиртуальный базовый класс, неважно, абстрактный или нет, однозначно не используется как интерфейс. Всё это превосходно дружит с множественным наследованием реализаций. Какие ещё могут быть тут вопросы? Разве что к D. ![]() ![]() class IFoo {     virtual void f() = 0;     virtual void g() = 0; }; class Base {     void g() {} }; class Derived : public Base, public virtual IFoo {     void f() {} }; int main() {     Derived derived; // ошибка, Derived - абстрактный }   Добавлено Цитата Qraizer @  Окай, ща набросаю чего-нибудь. 	 applegame, приведи пример простенького сериализатора на D  | 
    
| 
         
         
         
          
           Сообщ.
           #205
          
          , 
          
         
         
        
       | 
    |
| 
         | 
      
         Цитата Qraizer @  Если не ошибаюсь, поправьте, если не если, Александреску задумал D не как убийцу C++, а как язык с ориентацией на парадигму обобщённого программирования и без груза обратной совместимости с чем бы то ни было, а значит и лишённого набившего в C++ оскомину. Ну автор темы не Александреску. Решили поспорить о D vs C++, почему бы и нет      Цитата  Остаётся только вопрос практичности результата там, где D якобы превосходит. Собственно и всё. А вы тут какую-то хрень обсуждаете. По большому счету именно этот вопрос мы и обсуждаем. Что могут дать возможности D и стоит ли оно того.  | 
    
| 
         
         
         
          
           Сообщ.
           #206
          
          , 
          
         
         
        
       | 
    |
| 
         | 
      
         Цитата Qraizer @  applegame, приведи пример простенького сериализатора на D. Набросал сериализатор/десериализатор. Постарался максимально обобщить, но возможны косяки. API простой, как пять копеек: ![]() ![]() stream.serialize(arg1, arg2, arg3 ...); // сериализует аргументы в stream, stream - любой объект для которого выполнима операция stream.rawWrite(const byte[]) stream.deserialize(arg1, arg2, arg3 ...); // десериализует аргументы из stream, stream - любой объект для которого выполнима операция stream.rawRead(byte[]) Из коробки поддерживаются: скаляры, массивы, структуры, классы. Классы и структуры сериализуются поле за полем, причем поля тоже могут быть классами или структурами или массивами и т.п. Если такая сериализация не нужна, можно для конкретных структур/классов сделать специализацию определив внутри функции rawRead и rawWrite (см. тест, структура Preved). сериализатор ![]() ![]() import std.traits; // сериализация скалярных типов данных void serialize(S, D)(S stream, auto ref const D data) if(isScalarType!D) {     stream.rawWrite(cast(const byte[])(&data)[0..1]); } // сериализация структур и классов void serialize(S, D)(S stream, auto ref const D data) if(isAggregateType!D) {     // проверяем не определен ли член rawWrite     static if(hasMember!(D, "rawWrite")) {         data.rawWrite(stream);     } else {         // перебираем все члены структуры/класса         foreach(ident; __traits(allMembers, D)) {             // отсекаем функции, перечисления и прочую несериализуемую лабудень             static if(is(typeof(mixin("D." ~ ident ~ ".offsetof")))) {                 mixin("serialize(stream, data." ~ ident ~ ");");             }         }     } } // сериализация массивов void serialize(S, D)(S stream, auto ref const D data) if(isArray!D) {     // тип элемента     alias E = typeof(data[0]);     // сначала пишем длину     serialize(stream, data.length);     // если длина больше нуля, то пишем данные.     if(data.length) {         // если это массив скаляров, то пишем одним куском, иначе сериализуем поэлементно         static if(isScalarType!E) {             stream.rawWrite(cast(const byte[])data[]);         } else {             foreach(ref element; data) {                 serialize(stream, element);             }         }     } } // десериализация, аналогично сериализации void deserialize(S, D)(S stream, ref D data) if(isScalarType!D) {     stream.rawRead(cast(byte[])(&data)[0..1]); } void deserialize(S, D)(S stream, ref D data) if(isAggregateType!D) {     static if(hasMember!(D, "rawRead")) {         data.rawRead(stream);     } else {         foreach(ident; __traits(allMembers, D)) {             static if(is(typeof(mixin("D." ~ ident ~ ".offsetof")))) {                 mixin("deserialize(stream, data." ~ ident ~ ");");             }         }     } } void deserialize(S, D)(S stream, ref D data) if(isArray!D) {     alias E = typeof(data[0]);     size_t length;     deserialize(stream, length);     if(length) {         Unqual!E[] ndata;         ndata.length = length;         static if(isScalarType!E) {             stream.rawRead(cast(byte[])ndata[]);         } else {             foreach(ref element; ndata) {                 deserialize(stream, element);             }         }         data = cast(D) ndata;     } } // функции-хелперы для сериализации/десериализации сразу нескольких значений void serialize(S, ARGS...)(S stream, auto ref const ARGS args) if(ARGS.length > 1) {     foreach(ref arg; args) serialize(stream, arg); } void deserialize(S, ARGS...)(S stream, ref ARGS args) if(ARGS.length > 1) {     foreach(ref arg; args) deserialize(stream, arg); } тест ![]() ![]() import std.stdio; import std.algorithm; import serializer; // примитивная структурв struct Foo {     int fi;     bool fb;     string fs; } // класс с полем-структурой class Bar {     int fi;     bool fb;     string fs;     Foo ff;     this(int i, bool b, string s, Foo f) {         fi = i; fs = s; ff = f;     }     this() {}     bool isSame(const Bar o) const {         return fi == o.fi && fb == o.fb && fs == o.fs && ff == o.ff;     } } // структура с переопределенными операциями сериализации/десериализации struct Preved {     private string m_medved;     void rawWrite(S)(S stream) const {         stream.serialize("preved", m_medved);     }     void rawRead(S)(S stream) {         string signature;         stream.deserialize(signature);         assert(signature == "preved");         stream.deserialize(m_medved);     } } void main() {     // готовим тестовые данные     int s_int = 10;     string s_string = "hello";     Foo s_foo = Foo(123, true, "foo");     Bar s_bar = new Bar(42, false, "bar", Foo(345, false, "foobar"));     Foo[] s_foos = [         Foo(11, true, "foos1"),         Foo(22, false, "foos2"),         Foo(33, true, "foos3")     ];     Preved s_preved = Preved("medved");     auto file = File("test.txt", "w");     // сериализуем в файл     file.serialize(s_int, s_foo, s_string, s_bar, s_foos, s_preved);     /******************************************************************/     // переменные для десериализации     int d_int;     string d_string;     Foo d_foo;     Bar d_bar = new Bar;     Foo[] d_foos;     Preved d_preved;     file = File("test.txt", "rb");     // десериализуем из файла     file.deserialize(d_int, d_foo, d_string, d_bar, d_foos, d_preved);     // проверяем     assert(d_int == s_int);     assert(d_foo == s_foo);     assert(d_string == s_string);     assert(d_bar.isSame(s_bar));     assert(equal(d_foos, s_foos));     assert(d_preved == s_preved); }  | 
    
| 
         
         
         
          
           Сообщ.
           #207
          
          , 
          
         
         
        
       | 
    |
| 
         | 
      
          Ну, вот почему, почему всегда рефлексию показывают на этом тупом примере сериализации всех полей?  
        
          | 
    
| 
         
         
         
          
           Сообщ.
           #208
          
          , 
          
         
         
        
       | 
    |
| 
         | 
      
          Ну сериализатор его попросили написать. Если для составного типа не задана функция сериализации, то проход по полям лучше бинарной записи.   
        
       | 
    
| 
         
         
         
          
           Сообщ.
           #209
          
          , 
          
         
         
        
       | 
    |
| 
         | 
      
         Цитата D_KEY @  Если для составного типа не задана функция сериализации, то он не сериализуем вообще fixed. Да и я спрашиваю вообще, а не про именно сейчас.  | 
    
| 
         
         
         
          
           Сообщ.
           #210
          
          , 
          
         
         
        
       | 
    |
| 
         | 
      
         Цитата MyNameIsIgor @  Цитата D_KEY @  Если для составного типа не задана функция сериализации, то он не сериализуем вообще fixed. Ну тебя же не смущает дефолтный конструктор копирования, например. Если все поля у объекта сериализуемы, то почему бы и не сериализовать, раз просят.  |