Delphi vs C++ vs C#
, ну и Java немножко, где-то ближе к старшему байту номеров страниц
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
| ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
| [216.73.216.192] |
|
|
Правила раздела:
| Страницы: (495) « Первая ... 422 423 [424] 425 426 ... 494 495 ( Перейти к последнему сообщению ) |
Delphi vs C++ vs C#
, ну и Java немножко, где-то ближе к старшему байту номеров страниц
|
Сообщ.
#6346
,
|
|
|
|
Цитата MyNameIsIgor @ На сколько я помню лоровскую тему, на плюсах это не получилось сделать, в отличие от Java и Haskell ![]() Хотя я могу и ошибаться, ибо не совсем понял задание... Возможно, на плюсах просто сделали иначе. Ты имеешь в виду тему 2009-го года? Если да, то я не знаю, почему там не предложили код, подобный тому, что тут неоднократно проскакивал в разных спорах (пишу условно): ![]() ![]() template<typename H, typename T> struct List { H head; T tail; }; struct Nil {}; соответственно ![]() ![]() template<typename H, typename T> H head (List<H, T> x) { return new List<H, T>( x, xs ); } template<typename H> List<H> head (Nil xs) = 0; или как-то так. Или я что-то путаю? |
|
Сообщ.
#6347
,
|
|
|
|
Цитата korvin @ соответственно ![]() ![]() template<typename H, typename T> H head (List<H, T> x) { return new List<H, T>( x, xs ); } template<typename H> List<H> head (Nil xs) = 0; или как-то так. Тогда уж как-то так: ![]() ![]() template<typename H, typename T> H head (List<H, T> x) { return x.head; } void head(Nil xs); // не определять реализацию, тогда будет ошибка во время компиляции только из-за отсутствия возвращаемого значения, ну или на этапе линковки в любом случае |
|
Сообщ.
#6348
,
|
|
|
|
Цитата korvin @ Ты имеешь в виду тему 2009-го года? Да Цитата korvin @ Или я что-то путаю? Дело в том, что вы показываете практически списки типов, которые наполняются статически, а требование - заполнить список динамически. Парадоксально, но для Java прокатывало потому, что дженерики не инстанцируются как шаблоны. Но я тоже думаю, что возможно сделать на плюсах, там решения приводили. Но, на мой взгляд, нужно делать иначе, чем на Java. Сейчас, к сожалению, нет времени. Может, кто-нибудь из присутствующих потратит время. |
|
Сообщ.
#6349
,
|
|
|
|
Я может уже переработался, но по-моему достаточно к моему варианту добавить абстрактный класс с соответствующими виртуальными методами и унаследовать от него только общий случай шаблона, а специализацию для 0 оставить без такого наследования. Тогда можно динамически выстраивать список, примерно так же, как в яве. Не?
Добавлено Кроме того, если вся проблема в инстанцировании, можно вручнуь обеспечить поведение как у дженериков, через нетипизированные указатели В общем, будет время почитаю ту тему... |
|
Сообщ.
#6350
,
|
|
|
|
Цитата D_KEY @ Я может уже переработался, но по-моему достаточно к моему варианту добавить абстрактный класс с соответствующими виртуальными методами и унаследовать от него только общий случай шаблона, а специализацию для 0 оставить без такого наследования. Тогда можно динамически выстраивать список, примерно так же, как в яве. Не? Я эту тему видел года полтора назад. Пролистал, что-то в показанном решении на плюсах не понравилось (не помню уже что). Отметил для для, почему получилось для Java, и благополучно забил. Так что скорее всего я уже всё забыл и чушь говорю, а не ты переработал. |
|
Сообщ.
#6351
,
|
|
|
|
Цитата MyNameIsIgor @ Дело в том, что вы показываете практически списки типов, которые наполняются статически, а требование - заполнить список динамически. Парадоксально, но для Java прокатывало потому, что дженерики не инстанцируются как шаблоны. Но я тоже думаю, что возможно сделать на плюсах, там решения приводили. Но, на мой взгляд, нужно делать иначе, чем на Java. Сейчас, к сожалению, нет времени. Может, кто-нибудь из присутствующих потратит время. Ну хаскельные тайпклассы "инстанцируются" в компайл-тайме. |
|
Сообщ.
#6352
,
|
|
|
|
Цитата korvin @ Цитата MyNameIsIgor @ Дело в том, что вы показываете практически списки типов, которые наполняются статически, а требование - заполнить список динамически. Парадоксально, но для Java прокатывало потому, что дженерики не инстанцируются как шаблоны. Но я тоже думаю, что возможно сделать на плюсах, там решения приводили. Но, на мой взгляд, нужно делать иначе, чем на Java. Сейчас, к сожалению, нет времени. Может, кто-нибудь из присутствующих потратит время. Ну хаскельные тайпклассы "инстанцируются" в компайл-тайме. Ты не понял. В С++ происходит полное создание кода(генерация). Поэтому будет происходить бесконечное инстанцирование нового шалона при попытке скомпилировать в С++ один в один переписанный тот Java-код |
|
Сообщ.
#6353
,
|
|
|
|
Ты тоже немного не понял, я и не говорю, что при решении на С++ нужно ориентироваться на джаву. Нужно на хаскелл
|
|
Сообщ.
#6354
,
|
|
|
|
Цитата korvin @ Ну хаскельные тайпклассы "инстанцируются" в компайл-тайме. Дженерики тоже инстанцируются compile-time. Но инстанцируются один раз. Подозреваю, что тайпклассы ведут себя так же. |
|
Сообщ.
#6355
,
|
|
|
|
Цитата korvin @ Ты тоже немного не понял, я и не говорю, что при решении на С++ нужно ориентироваться на джаву. Нужно на хаскелл Прочитал таки ту тему. Вы меня извините, но код на Java/С# не решает поставленную задачу. Равенство длин списков там обеспечивается лишь за счет симметричного конструирования двух списков(что можно сделать обычным for'ом). При использовании generic'ов стирается информация о типе-параметре, потому Cons<Nil> имеет тот же тип, что Cons<Cons<Nil>> и т.д., потому гарантировать равную длину компилятор не в состоянии. И ему, в отличие от Haskell'я можно подсунуть списки разной длины - ошибка будет, но в рантайме, при попытке вычисления результата. В Haskell'е, насколько я понял, за счет тайпклассов достигается просто гарантия того, что на каждой итерации построения у двух списков будут таки одинаковые типы(и длины, в данном случае), при этом информация о типах всего списка не сохраняется(как происходит в наивной попытке реализации на С++). Думаю, что можно так же сделать и в С++, через, как я говорил, введение промежуточных (абстрактных) классов, которые в итоге предотвратят постоянное инстанцирование шаблона функции. |
|
Сообщ.
#6356
,
|
|
|
|
Цитата D_KEY @ Прочитал таки ту тему. Вы меня извините, но код на Java/С# не решает поставленную задачу. Равенство длин списков там обеспечивается лишь за счет симметричного конструирования двух списков(что можно сделать обычным for'ом). При использовании generic'ов стирается информация о типе-параметре, потому Cons<Nil> имеет тот же тип, что Cons<Cons<Nil>> и т.д., потому гарантировать равную длину компилятор не в состоянии. А в Haskell'е не так что ли? Там так же конструирование списка происходит симметрично. Если я не прав, то скажите, какого типа будет список длиной, введённой пользователем? Как написать этот тип в программе? |
|
Сообщ.
#6357
,
|
|
|
|
Вы об этом говорите: http://migmit.livejournal.com/32688.html ?
|
|
Сообщ.
#6358
,
|
|
|
|
Об этом. Но по-моему кто-то выдает желаемое за действительное.
|
|
Сообщ.
#6359
,
|
|
|
|
Толи я плохо знаю шарп, толи в упор не вижу никакой статики. Всё ж в динамике считается. В т.ч. и длинна.
|
|
Сообщ.
#6360
,
|
|
|
|
Цитата Повстанець @ Толи я плохо знаю шарп, толи в упор не вижу никакой статики. Всё ж в динамике считается. В т.ч. и длинна. ![]() Список формируется динамически, длина вычисляется динамически, а задача в том, что бы статически доказать, что два списка имеют одну длину при любом ходе выполнения(и заругаться на этапе компиляции, если это не так). Тут надо смотреть изначальный код на Haskell'е: ![]() ![]() module Test where data Nil = Nil data Cons a = Cons Integer a class ScalarProduct a where scalarProduct :: a -> a -> Integer instance ScalarProduct Nil where scalarProduct Nil Nil = 0 instance ScalarProduct a => ScalarProduct (Cons a) where scalarProduct (Cons n1 a1) (Cons n2 a2) = n1 * n2 + scalarProduct a1 a2 main :: Integer -> Integer main n = main' n 0 Nil Nil where main' :: ScalarProduct a => Integer -> Integer -> a -> a -> Integer main' 0 _ as bs = scalarProduct as bs main' n i as bs = main' (n-1) (i+1) (Cons (2*i+1) as) (Cons (i^2) bs) Если ты ошибешься и попробуешь написать так: ![]() ![]() main' (n-1) (i+1) (Cons (2*i) (Cons (2*i+1) as)) (Cons (i^2) bs) Т.е. сформировать списки разной длины, то их типы не совпадут и компилятор заругается. Вот только мне кажется, что код на Java/C# не решает эту задачу. |