Здравствуйте, Аноним, Вы писали:
А>И в чем их смысл? В частности char_traits, например.
Очень хорошо объяснено в книге "Решение сложных задач на С++" Саттера, смотри задачу 1.11
Это пример класса свойств (описание в стандарте п.17.1.18)
char_traits<T> предоставляет информацию о символоподобном типе T. Как его сравнивать например. Вообще используетсяч в тех случаях когда инофрмацию о типе желательно содержать в отдельном классе.
Re: Объясните, дураку, на пальцах, что есть traits?
Здравствуйте, Аноним, Вы писали:
А>И в чем их смысл? В частности char_traits, например.
Согласно стандарту на STL char_traits позволяет специализировать как трактовать (интерпретировать) тот или иной символ. Так, например в одной кодировке символ может быть буквой, а в другой числом (более "на пальцах" даже и не знаю как).
Цитата:
"Различия в кодировках существенны для обработки строк и ввода/вывода". Например , признак "конца файла" и конкретные особенности сравнения символов могут различаться в зависимости от реализации. Классы трактовок определяют все основные свойства типа символов и операции, необходимые для реализации строк и потоков данных, как статических компонентов. "
Re[2]: Объясните, дураку, на пальцах, что есть traits?
Здравствуйте, DangerDen, Вы писали:
А>>И в чем их смысл? В частности char_traits, например.
DD>Очень хорошо объяснено в книге "Решение сложных задач на С++" Саттера, смотри задачу 1.11
DD>Это пример класса свойств (описание в стандарте п.17.1.18)
DD>char_traits<T> предоставляет информацию о символоподобном типе T. Как его сравнивать например. Вообще используетсяч в тех случаях когда инофрмацию о типе желательно содержать в отдельном классе.
Еще на мой взгляд, блестяще написано в книге Шаблоны С++. В той главе, где разбираетсяобобщенный алгоритм вычисления среднего.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[2]: Объясните, дураку, на пальцах, что есть traits?
Здравствуйте, Аноним, Вы писали:
А>И в чем их смысл? В частности char_traits, например.
В расширении, группировке и обобщении инструментария, относящегося к тому или иному типу.
Допустим, у нас есть некий класс T, и нам потребовалось добавить функциональность — приведение к целому и обратно.
Казалось бы, нет проблем: вводим в его определение три имени:
class T
{
...
public: // convert to/from inttypedef ??? integral_type; // потому что может статься, что int не всегда нас устраивает
integral_type to_integral() const;
static T from_integral(integral_type); // либо конструктор; но производящая функция - это более общее решение
};
Чем это плохо?
1) Если таких классов много, то придётся в каждый из них включить подобную функциональность. А не факт, что можно модифицировать их определения
2) Для простых типов — определения модифицировать нельзя.
Ну ладно, нельзя так нельзя — специально для этого вводятся операции НАД типом, т.е. перегруженные внешние функции.
someint to_integral(const T& src); // тип результата - по желанию.
// Жаль, что пропал идентификатор типа, специфичного для T, ну да фиг с нимtemplate<class _> void from_integral(someint){} // первичное объявление шаблонаtemplate<> T from_integral<T>(someint src); // и его специализация для конкретного типа
Чем плохи шаблоны функций со свободными (не выводимыми из аргументов) параметрами шаблона — уже говорилось недавно.
Начиная с неоднозначности и нетривиальных приоритетов при выборе той или иной специализации.
И ещё остаются проблемы, связанные с автоматическим приведением типов аргументов. Полагаясь на выведение типа выражения, можно приплыть в неожиданном направлении.
Кроме того, мы получаем россыпь. Ладно конверсия, это всего лишь пара функций. А та же работа с символами, где функций больше десятка?
Кроме того, покуда нет шаблонных typedef'ов и шаблонных же переменных, мы не можем вводить их иным способом, как завести некий вспомогательный класс по шаблону, параметризованному данным типом.
Он и будет являться traits'ом.
// первичное объявление шаблонаtemplate<class XZ> struct integral_traits
{
typedef int inegral_type; // по умолчанию, intstatic integral_type to(const XZ& src) { return to_integral(src); }
// по умолчанию, надеемся, что есть глобальная функцияstatic XZ from(integral_type src) { XZ dst; from_integral(src,dst); return dst }
// по умолчанию, надеемся, что есть глобальная функция с out-параметром
};
template<> struct integral_traits<T> // для нашего любимого, со встроенной функциональностью
{
typedef T::integral_type integral_type;
static integral_type to(const T& src) { return src.to_integral(); }
static T from(integral_type src) { return T::from_integral(src); }
}
Наконец, мы можем действовать довольно изощрённо: если классы T, U, V являются моделью "ВстроенныйКонвертор", то можем обобщить эту специализацию
template<class XZ>
struct integral_traits_embedded
{
typedef XZ::integral_type integral_type;
static integral_type to(const XZ& src) { return src.to_integral(); }
static XZ from(integral_type src) { return XZ::from_integral(src); }
};
template<class XZ>
struct integral_traits_outer
{
typedef int inegral_type; // по умолчанию, intstatic integral_type to(const XZ& src) { return to_integral(src); }
static XZ from(integral_type src) { XZ dst; from_integral(src,dst); return dst }
};
template<class XZ>
struct is_embedded_integral_convertor
{
enum { value = ????? }; // для не-конверторов - false
};
// определение этого свойства (ещё один traits!) может быть автоматизированным
// или же у каждого класса-конвертора должна быть своя специализацияtemplate<class XZ>
struct integral_traits : typename boost::mpl::if_c<
is_embedded_integral_convertor<XZ>::value,
integral_traits_embedded<XZ>,
integral_traits_outer<XZ>
>::type
{
};
Здесь мы увидели ещё одно применение traits'ов — а именно, паттерн "Стратегия". Определение (при компиляции) и поведение (при исполнении) окончательной версии integral_traits зависит от того, какая стратегия — integral_traits_embedded | integral_traits_outer — будет выбрана, мы станем пользоваться тем или иным комплектом функций.
Перекуём баги на фичи!
Re[2]: Объясните, дураку, на пальцах, что есть traits?
От:
Аноним
Дата:
14.01.05 04:30
Оценка:
Здравствуйте, Кодт, Вы писали:
К>В расширении, группировке и обобщении инструментария, относящегося к тому или иному типу.
респект.
Re[2]: Объясните, дураку, на пальцах, что есть traits?
Класс, просто супер. Только одно ИМХО с моей стороны. Свойства(tairs) и Странегии, это разные вещи. Свойства связаны с типом, а стратегии связаны алгоритмом. Или — "Стратегия имеет много общего со свойствами, но отличается от них тем, что в них меньше внимания уделяется типам и больше — поведению" (с)Александреску. Граница между ними размыта, но она все же есть, можно заметить что Стратегия евляется распостраненным паттерном проектипования, который можно реализовать на разных яжыках притендуюших на объектность, свойство же — технология рожденная сообшеством С++, и не переносима на все ОО языки.
---
Re[3]: Объясните, дураку, на пальцах, что есть traits?
Здравствуйте, Chez, Вы писали:
C>Здравствуйте, AlexEagle, Вы писали:
AE>>Здравствуйте, Аноним, Вы писали:
AE>>RE: сабж
AE>>Ну дык назовись для начала C>сказано: дурак. Что тебе ещё надо?
Смешно, но лучше удалить, а то обидется человек...
Компьютер сделает всё, что вы ему скажете, но это может сильно отличаться от того, что вы имели в виду.
Re[4]: Объясните, дураку, на пальцах, что есть traits?
Характеристики (traits) — это метод обобщенного программирования, позволяющий принимать решения на этапе компиляции программы, основываясь на информации о типах, аналогично тому, как в ходе выполнения программы принимаются решения , основанные на значениях.
(с)Александреску