Как стать автором
Обновить

Комментарии 64

Да, это именно то, чего мне не хватало все эти года :-) Если бы каждый программист как-можно больше фич реализовывал с помощью шаблонов — мы жили бы в чудесном мире производительности и ослепительного света прогресса.
Прошу прощение, при всем моем уважении к вам — либо у вас сперли аккаунт, либо вы написали бота ) Столько BarsMonster'a на Хабре и в таком формате Мир еще не видывал. Смайлик из прошлого, практически в каждом посте — первый же комментарий, комментарии уровня среднестатистического хабрапетросяна вместо адекватных ответов (с вашим то багажом знаний, блин), топики уровня «поправим пару строк в виндовом реестре на питоне» & etc. Где старый добрый профи с клевым доменом в одной руке и симпатичной сестрой в другой? Неужели ППА головного мозга? Или рейтинг?

Сорри за выхлоп.
Перенервничал? =))
Noooooooo! My first place on Habr is gone!


Барс, без обид))
Да ладно :-)
Чем больше я там, тем больше хочется прибить акк (или сделать свой с блекджеком).
Есть всего один топик, который я действительно хочу опубликовать.
Чего? Рейтинг на Хабре ведь ни к чему не обязывает. Ну первый ты, ну тысячный, никакой разницы, имхо)
Топики надо публиковать от души, имхо)
Вот, ты живешь в чудесном мире, и я рад за тебя :-)
Не, ну честно, а какая разница то?)
Все банально — для одной из будущих статей нужно быть на первом месте. Ну и мне понравилось как сестра случайно обнаружила меня на первом месте и была в полном шоке :-) — впрочем, это уже не повториться…

Самолюбие это само собой не тешит — т.к. на хабре достаточно несложно выйти на первое место — нужно просто подарить много-много своего времени(даже уметь программировать совершенно не обязательно). А дороже времени для меня ничего нет.
Я имею ввиду другое
Чем больше я там, тем больше хочется прибить акк (или сделать свой с блекджеком).

Чего? Чем так плохо первое место? Оно что есть, что нету.
Оно что есть, что нету если оно не нужно. А если нужно — тогда это как стоять в середине горной реки :-)
Ну тогда я поделаю тебе волны ;)
Weeeee…
Этот комент сведет мой сервер в могилу ) Я то думаю, откуда столько переходов на мой сайт отсюда… 900 за 2 часа… А как днем все начнут рефрешить коменты…
Черд, не тот урл:
PS. Когда уже будет редактирование комментов в течении 5 минут…
Вот это мысль верная.
Да-да, сперли :-) Бота все хотел — но пока никак.
ППА мне не светит, я по прежнему хочу от неё отказаться.

Насчет уровня можно спорить, но не публично. В данном конкретном случае — вырвалось моя личная неприязнь к злоупотреблению языком — последствия тяжелого детства.
А чего буквы такие маленькие? Стесняетесь что-ли?
Не хотелось совершенно оффтопный коммент делать на полстраницы, а выхлопнуться нужно было.
Ну, все вроде бы супер! Только, в течении 10 минут пытался ответить себе на вопрос — «Где бы мне это понадобилось?». Или пятница-ночь, или я не дорос пока:)
Александреску и другие замечательно показывают где и зачем. Boost и STL так же.
Если Вы говорите про метапрограммирование, то оно должно сохранять принципы обобщенного программирования, а в приведенных примерах, я обобщенности не увидел. Но, это как в том бородатом анекдоте: "...-Видишь зайца? — Нет. -Вот и я не вижу, а он есть!":) Буду читать Александреску.
Без осмысления тривиальных примеров не стоит даже открывать Александреску.

Пост является затравкой для привлечения народа к теме + возможный обмен опытом, но никак не best practices и им подобные. Для последнего лучше читать книги Александреску.
Очень даже стоит открывать Александреску. Просто придётся разок-другой перечитать, дабы достигнуть полного сатори от C++ных наблонов.
Кстати, мне когда советовали Александреску, уточняли, что читать надо лежа на полу, чтобы не откуда падать.
НЛО прилетело и опубликовало эту надпись здесь
А с чего вы решили, что оно кому-то что-то должно? Оно есть, у него свои возможности, как их использовать — дело каждого.
Читайте, читайте, там много полезного.
Такие фокусы как правило используются в библиотеках типа boost для организации несвойственных языку вещей — делегатов, грамматик, кортежей и иже с ними. Грамотная реализация того же делегата требует достаточно сложной шаблонной магии O_O.
шаблоны должны остаться шаблонами, а не задачкой для реализации машины Тьюринга ))
Как ещё предлагаете заниматься мета-программированием в C++? Ведь это банальное управление генерацией кода, которое рано или поздно понадобится в каком-нибудь сложном софте. C++ — не Lisp, AST-макросов там нет. Выкручиваемся, как можем.
так где же это может пригодиться за рамками истинного предназначения шаблонов (коллекции, алгоритмы, итераторы и т.п.)? может стоит воспользоваться специализированными инструментами? например, ORM-генераторы классов, если таковые необходимы.
Истинное предназначение шаблонов — удобная и упрощающая разработку генерация кода.
с чего вы взяли, что шаблоны C++ код генерят?
Есть и те, что непосредственно не генерят. Но, в конечном счёте, они служат именно этой цели: шаблоны обобщают алгоритмы и структуры данных и служат для генерации специализированных версий этих алгоритмов и структур. А это, в свою очередь, позволяет выполнять некоторые вычисления на этапе компиляции, что есть неявная генерация кода. Похоже, вы воспринимаете термин «генерация кода» на слишком очевидном уровне: сгенерить из C++ машинный код.
так всё же, какие вычисления на этапе компиляции необходимы, кроме вычисления типа? я уже второй раз прошу дать пример, имеющий смысл в реальном проекте, если он имеется. в теории все мне понятно. я тоже эту головоломку решал с факториалами, но практического значения в этих «выкрутасах» так и не увидел.
пример: есть подсистема Property, поддерживает из коробки любые типы. Для того чтобы зарегестрировать в системе свойство нужно вызвать MakeProperty:

class CMyObject: public CPropertyEnabled
{
int a;
double x;
std::vector v;

DECLARE_META_CLASS();
};



IMPLEMENT_META_CLASS( CMyObject )
{
// Здесь мы задаем список свойст, поддерживаемых нашим классом
RegisterProperty( MakeProperty( &CMyObject::a, «a» ).release() );
RegisterProperty( MakeProperty( &CMyObject::x, «x» ).release() );
RegisterProperty( MakeProperty( &CMyObject::v, «v» ).release() );
}

// а вот так свойствами можно пользоваться:

CMyObject obj;

MakeTransaction().MakeTrampoline( &obj )
.SetPropertyValue( «a», 1 )
.SetPropertyValue( «x», «1.0» )
.SetPropertyValue( «v», "{1,2,3}" )
.Close();

assert( obj.a == 1 );
assert( obj.x == 1.0 );
assert( obj.v[0] == 1 );
assert( obj.v[1] == 2 );
assert( obj.v[1] == 3 );

А теперь обратите внимание, на то, что
1. RegisterProperty( MakeProperty(… ).release() ) выглядит абсолютно одинаково для свойств совершенно разных типов (у нас в с++ строгая типизация, напомню).
2. Каким-то магическим образом SetProperty может принимать не только реальный тип свойства, но и что-то, что можно в него адекватно сконвертировать (например, строку «1.5» в число 1.5)
3. Свойства контейнерных типов можно использовать так же как и сами контейнеры (но все обращения будут при этом идти через транзакцию, которую можно откатить):
auto oTransaction = MakeTransaction();
auto &rv = oTransaction.MakeTrampoline( &obj, «v» );
std::for_each( rv->begin(), rv->end(), [](… &r ){ r = (int)r + 1; } );

Так вот, это работает, потому как MakeProperty штука хитрая, при компиляции это:
RegisterProperty( MakeProperty( &CMyObject::a, «a» ).release() );

преобразуется приблизительно в следующее:
RegisterProperty(
MakeEmptyProperty( «a» )
.SetSetter( []( CMyObject *p, int v ){ p->a = v; } ) // как устанавливать свойство
.SetGetter( []( const CMyObject *p ){ return p->a; } ) // как читать свойство
.RegisterConversionTrampoline< std::string, int >(… ) // преобразование string->int
.RegisterConversionTrampoline< int, std::string >(… ) // преобразование string->int
.release() );

(трамплинов преобразований на самом деле больше, для контейнеров дополнительно устанавливаются функции, позволяющие получить begin, end, конкретный элемент, и т.п.)

так вот MakeProperty работает на шаблонах: анализируя переданный ей тип она старается как можно более точно описать, как генерировать для него свойства:
* если тип поддерживает сериализацию через стримы, зарегестрировать преобразователи из/в строковые типа
* если тип является константным не регестрировать setter (тогда свойство будет ридонли)
* если тип контейнер, зарегестрировать логику, специфичную для контейнеров и т.п.
шаблоны — полный по тьюрингу чисто функциональный язык, оперирующий типами. с помощью шаблонов генерируются новые типы классов.
кроме вычисления типа и генерации классов (методов, функций) нужны ли еще какие-то возможности от шаблонов? я думаю, что нет. так как при технической возможности вычислять факториал на этапе компиляции, затраты на реализацию подобного простейшего алгоритма чудовищны. проще отдельный генератор написать, если так уж необходимо генерировать исходный код. свою же шаблонную роль шаблоны отлично выполняют ))
Шаблоны позволяют определять такие штуки как:
* наследуется ли А от B?
* имеет ли А функцию-член f()
* и т.п.

Эти вещи очень сильно бывают нужны в обобщенном коде.

Вообще, ничего сложного там нету, надо только понять, что шаблоны — это функциональный язык с несколько кривым синтаксисом.

А смысл? Если мне нужно вычислить преобразование фурье некоего константного сигнала, я пишу простую и понятную программку (без всякой там шаблонной магии), с обычными циклами, а результат просто забиваю в Си-шный массив. Смысл мозг пудрить?
НЛО прилетело и опубликовало эту надпись здесь
Можно но не очень удобно когда нужно объявлять такие числа часто (например в разных исходных файлах) или они часто меняются по мере разработки.
Это такой чистый акт творчества. Как и вычисление факториала на этапе компиляции — практического применения не имеет.
Да и вообще, по ссылке не вычисляют FFT, а разворачивают в линейный код — это большая разница.
Если таки вы попробуете сказать
min(2.0, 3)

специализация для дабла не сгенерится, а сгенерится ошибка компиляции. В случае вашего шаблона придётся писать:
min<double>(2.0, 3)

Полностью согласен, ошибка исправлена.
НЛО прилетело и опубликовало эту надпись здесь
Ну дык, факториал на шаблонах и есть забава. Но вообще шаблонное мегапрограммирование попрошу не трогать!
НЛО прилетело и опубликовало эту надпись здесь
Спасибо, посмеялся :-) Я его не то чтобы люблю, это просто как глоток свежего воздуха после повседневного мяса.
Пошли на мою работу сходим, подебажим и порефакторим твои любимые шаблоны ;-)
Только нужно учитывать, что за рабочий день мы проект собрать сможем только 1 раз ;-)
Извиняй, до тебя далеко добираться :-)
Спасибо, Кэп! (простите, не сдержался)
Как-то давно, узнав о такой возможности, написал вычисления определителя матрицы в compile-time.

Кстати, интересно, что МП на шаблонах в Си++ — чистый функциональный язык.
ага, только при оптимизациях и функция вычисляющая факториал редуцируется до своего значения, а вашу байду нельзя применить для переменных
This is useless, sad but true
У Васи было два компьютера. Один он выбросил в окно. Сколько компьютеров осталось у Васи?

Вроде всё правильно, но бессмыслица абсолютная. Присоединяюсь к мнению тех, кто считает, что демонстрационные задачи должны быть интересными и жизненными.
>а вот интересно, можно ли сделать compile-time рендеринг мандельброта на шаблонах C++?
мне было интересно www.gamedev.ru/flame/forum/?id=90646&page=2#m25
Меня в свое время очень сильно впечатлило использование шаблонной магии применительно к микроконтроллерам для абстрагирования драйвера внешнего устройства от пинов, к которым оно подключено.
easyelectronics.ru/rabota-s-portami-vvoda-vyvoda-mikrokontrollerov-na-si.html
Идее уже больше десяти лет вообще-то :-)
В следующем стандарте будет интереснее (попробовать можно уже сейчас: gcc.gnu.org):
constexpr int fact(int n)
{
if (n > 0)
return fact(n - 1);
else
return 1;
}
double array[fact(5)];


Или даже ещё лучше:

struct CompileTimeMap {
size_t hash;
const char* val;
} ctmap[] = { hash("123"), "123" };

Плюс обобщить макросом вида "#define CTH(str) hash(str), str".
В § 7.1.5 п. 3 говорится, что в теле constexpr функции может быть только один return и никаких if.
Т.е. хотя бы так:

constexpr int fact(int n) { return n > 0 ? fact(n - 1) : 1; }
Совершенно верно.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации