Delphi vs C++ vs C#
, ну и Java немножко, где-то ближе к старшему байту номеров страниц
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
| ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
| [216.73.216.192] |
|
|
Правила раздела:
| Страницы: (495) « Первая ... 365 366 [367] 368 369 ... 494 495 ( Перейти к последнему сообщению ) |
Delphi vs C++ vs C#
, ну и Java немножко, где-то ближе к старшему байту номеров страниц
|
Сообщ.
#5491
,
|
|
|
|
Цитата D_KEY @ Ну там не один в один соответствие, все-таки разные плюшки... Ты приведи показательный пример на тайпклассах, я попробую как-нибудь сделать через traits. показательный пример чего? трейтов? как я могу привести показательный пример, если не знаю, что показывать? =) впрочем попробую: ![]() ![]() module Classes ( Point(..) ) where class Point a where getX :: a -> Int getY :: a -> Int ![]() ![]() module Traits ( Color(..), Colored(..) ) where data Color = RGB Int Int Int class Colored a where getColor :: a -> Color ![]() ![]() module Main where import Classes import Traits data MyPoint = MyPoint Int Int Color instance Point MyPoint where getX (MyPoint x _ _) = x getY (MyPoint _ y _) = y instance Colored MyPoint where getColor (MyPoint _ _ c) = c оно? |
|
Сообщ.
#5492
,
|
|
|
|
Все-таки юзкейсы разные, прогнал я про схожесть. Сейчас с телефона, код потом напишу
|
|
Сообщ.
#5493
,
|
|
|
|
Что-то вроде такого...
![]() ![]() template<typename T> struct PointTraits { static int getX(T); static int getY(T); }; ![]() ![]() struct Color { int r, g, b; }; template<typename T> struct ColoredTraits { static Color getColor(T); }; ![]() ![]() struct MyPoint { int x; int y; Color color; }; template<> struct PointTraits<MyPoint> { static int getX(const MyPoint &p) { return p.x; } static int getY(const MyPoint &p) { return p.y; } }; template<> struct ColoredTraits<MyPoint> { static Color getColor(const MyPoint &p) { return p.color; } }; Добавлено Странные немного получились trait'ы |
|
Сообщ.
#5494
,
|
|
|
|
а нафик ты Point описал как трейт? это ж должен быть простой класс. как я понял трейты -- это те же примеси, только с методами
|
|
Сообщ.
#5495
,
|
|
|
|
D_KEY, не проще было бы привести какой-нибудь std::numeric_limits<>?
|
|
Сообщ.
#5496
,
|
|
|
|
Цитата korvin @ а нафик ты Point сделал описал как трейт? это ж должен быть простой класс. как я понял трейты -- это те же примеси, только с методами Нет. Это классы-характеристики, т.е. именно набор некоторых дополнительных свойств типа. Так например numeric_limits предоставляет некоторые дополнительные параметры указанного типа чисел, char_traits содержит свойства для типов символов, а iterator_traits, соответсвенно, для типов итераторов. Причем сами типы могут не знать о trait'ах. Мне показалось, что юзкейс этого приема пересекается с юзкейсом тайпклассов... Добавлено Цитата Qraizer @ D_KEY, не проще было бы привести какой-нибудь std::numeric_limits<>? мне хотелось посмотреть, справятся ли trait'ы с типовым использованием тайпклассов. Теперь вижу, что хоть вроде как и справились, но такое использование не очень соответствует изначальной идеи. |
|
Сообщ.
#5497
,
|
|
|
|
korvin, использование будет выглядеть примерно так:
![]() ![]() template<typename T> int f(const T &point) { return PointTraits<T>::getX(point); } Еще можно сделать trait отдельным параметром, чтобы получить большую гибкость... Так, например, поступает basic_string: ![]() ![]() template<typename charT, typename traits = char_traits<charT>/*, ...*/> class basic_string; Т.е. по умолчанию используется std::char_traits для указанного типа символов(в стандартной библиотеки есть характеристики для char, wchar_t, char16_t, char32_t), но ты можешь подставить другой класс характеристик. Это позволяет использовать разные характеристики для одного типа символов. |
|
Сообщ.
#5498
,
|
|
|
|
Цитата D_KEY @ korvin, использование будет выглядеть примерно так: ![]() ![]() template<typename T> int f(const T &point) { return PointTraits<T>::getX(point); } чем это отличается от ![]() ![]() f :: Point t => t -> Int f p = getX p ? |
|
Сообщ.
#5499
,
|
|
|
|
Цитата korvin @ чем это отличается от Вот это я тебя и хотел спросить |
|
Сообщ.
#5500
,
|
|
|
|
ээм... а в чём изюминка trait'ов? (с виду напоминают helper'ы).
Добавлено эх далековато... |
|
Сообщ.
#5501
,
|
|
|
|
Цитата DesweR @ ээм... а в чём изюминка trait'ов? (с виду напоминают helper'ы). Helper'ы добавляют методы, насколько я помню. Здесь же мы имеем именно набор характеристик для типа. Кроме того мы можем написать шаблон реализации traits(сохранив возможность специализации), а так же создать несколько реализаций интерфейса traits для одного типа. Т.е. в общем случае имеем отношение многие ко многим. Посмотри на стандартные плюсовые строки. |
|
Сообщ.
#5502
,
|
|
|
|
D_KEY
А можно простенький конно-вакуумный пример на Foo Bar? |
|
Сообщ.
#5503
,
|
|
|
|
Цитата DesweR @ с виду напоминают helper'ы скорее перегрузку или просто обертки |
|
Сообщ.
#5504
,
|
|
|
|
Цитата DesweR @ D_KEY А можно простенький конно-вакуумный пример на Foo Bar? А пример выше с basic_string не ясен? На Foo Bar'е тут особо не объяснишь. Вот еще пример из стандартной библиотеки. Есть iterator_traits - характеристики итератора. В числе этих характеристик есть тип-тэг категории итератора(итератор ввода, итератор вывода, последовательный итератор, двунаправленный итератор или итератор произвольного доступа). Этим пользуется стандартная функция сдвига итератора на произвольное число позиций std::advance. Так, например, для последовательного итератора будет вызван инкремент нужное число раз, а итератор произвольного доступа будет сдвинут сразу одной операцией. Выбор, естественно, будет сделан в compile-time, на основе категории итератора. Добавлено Цитата korvin @ Цитата DesweR @ с виду напоминают helper'ы скорее перегрузку или просто обертки Ты уже объяснил мне разницу с тайпклассами? |
|
Сообщ.
#5505
,
|
|
|
|
Цитата DesweR @ А можно простенький конно-вакуумный пример на Foo Bar? ![]() ![]() package test.classes; public class Foo { public void foo() { System.out.println("Foo.foo()"); } } ![]() ![]() package test.classes; public class Gee { public void gee() { System.out.println("Gee.gee()"); } } ![]() ![]() package test.classes; public class Quux { public void quux() { System.out.println("Quux.quux()"); } } ![]() ![]() package test.traits; import test.classes.Foo; import test.classes.Gee; public class Bar { public static void exec(Foo foo) { System.out.print("Bar.exec(Foo) -> "); foo.foo(); } public static void exec(Gee gee) { System.out.print("Bar.exec(Gee) -> "); gee.gee(); } } ![]() ![]() package test.traits; import test.classes.Quux; public class Buz extends Bar { public static void exec(Quux quux) { System.out.print("Buz.exec(Quux) -> "); quux.quux(); } } ![]() ![]() package test; import test.classes.*; import test.traits.Buz; public class App { public static void main(String[] args) { Buz.exec(new Foo()); Buz.exec(new Gee()); Buz.exec(new Quux()); } } ![]() ![]() Bar.exec(Foo) -> Foo.foo() Bar.exec(Gee) -> Gee.gee() Buz.exec(Quux) -> Quux.quux() |