- 1
[](){}();
Нашли или выдавили из себя код, который нельзя назвать нормальным, на который без улыбки не взглянешь? Не торопитесь его удалять или рефакторить, — запостите его на говнокод.ру, посмеёмся вместе!
+170
[](){}();
Поздравляю с новым стандартом, товарищи!
( ( ) ( ( ) ) ( ) )
Приходится писать, что-то типа:
Притом уродский bind2nd не хочет принимать ссылки на var(приходится использовать указатель), хотя мог бы. И ptr_fun приходится использовать, хотя он тут совсем не нужен.
Или так пишем в старом стандарте, что ещё более громоздко:
А вот в новом стандарте такой проблемы нет:
Это куда читабельнее, меньше писать и удобнее.
Хотя было бы хорошо иметь вывод типов, но и так сойдет, ибо хоть что-то. :)
А ещё есть boost::function (он же отныне std::function). Незаменимый инструмент для создания методов, итерирующих некоторый инкапсулированный контейнер с вызовом функтора (с заданной сигнатурой, но совершенно произвольным типом) на каждом элементе. Альтернатива - только шаблонный метод, со всеми его недостатками вроде нестрогой типизации и необходимости реализации в заголовочном файле.
Можно привести пример использования boost::function в данной области, как замена биндигу/каррированию?
>std::function
>std::bind
Это есть только в новом стандарте, так что это лишь повод его "восхвалять".
Пример:
typedef boost::function<void(SceneNode&)> FunctorNodeRef;
void traverse(const FunctorNodeRef& functor);
Метод класса SceneNode, являющегося, собственно, узлом графической сцены. traverse проходит по всему поддереву сцены, начинающемуся с данного узла, и для каждого узла в поддереве вызывает функтор.
Вызов может выглядеть так:
void SomeClass::foo(SceneNode& node) {}
void SomeClass::bar()
{
node.traverse(boost::bind(&SomeClass::fo o, this, _1));
}
А может и так:
void globalFoo(SceneNode& node) {}
void SomeClass::bar()
{
node.traverse(globalFoo);
}
Один и тот же метод подходит для обоих вариантов.
> Это есть только в новом стандарте,
> так что это лишь повод его "восхвалять".
Я вроде бы и не говорил, что новый стандарт плох. Наоборот, рад, что он заимствует по-настоящему полезные вещи хотя бы из того же буста.
Поправка: алгоритмы STL удобнее использовать с лямбдами.
Заменяя это на:
typedef std::vector<std::string> Strings;
Strings strings;
...
for (Strings::iterator it = strings.begin(); it != it.end(); ++it)
{
...
}
Ещё, если не нужны именно итераторы (например, для удаления), есть вот такая (пускай и не стандартная) штука:
BOOST_FOREACH(const std::string& str, strings)
{
...
}
Разворачивается он, конечно в нечто адское (не знаю насчёт оптимальности), но если скорость не критична, то читабельность важнее, а оптимизациями займётся компилятор.
Короче, кто хотел решать проблемы - решил их для себя давно. Но auto - это тоже хорошо, не спорю. А лямбды - вообще отлично.
Всё равно это длинно.
>Разворачивается он, конечно в нечто адское (не знаю насчёт оптимальности), но если скорость не критична
Скорость выполнения не страдает. Скорость компиляции - запустил на перекомпиляцию и пошёл играть в домино:
http://xkcd.ru/i/303_v1.png
Скорость компиляции - это да. "Технологичный" код от этого страдает по определению. Помнится, позаимствовали как-то из того же буста библиотеку для стейт-машин. Почти всё выглядело красиво и удобно, но компилировалось под конец проекта минут 20-25 на машине с четырёхядерным процом и парой гигов оперативки.
На следующем проекте заимствовали только идеи. Самопальная "облегченная и усовершенстованная" либа работает в нашем контексте не хуже (даже лучше), компилируется при тех же масштабах в 4-5 раз быстрее. Что, конечно, тоже многовато. Но что делать - прогресс же.
У всех методов и систем есть отрицательные стороны. Главное не в том, для чего эти методы и системы можно использовать, а в том, как их применяют.
Используя атомные исследования, не обязательно создавать ядерную бомбу, у них есть и мирные применения.
auto всеж лучше, чем any или dynamic.
На моей генту компиляция chromium с его WebKit - дело довольно долгое и унылое, занимающее несколько часов. Ядро же компилится 20 минут.
у меня минуты 2-3 забирает
HINT:core2duo 2,4Ghz + ccache
За джва года с половиной года явно прогорело и потухло, уважаемый некромант :)
... играя на балалайке. А потом вы пьете водку с ним и медведем.
for (auto it : v)
{
}
http://www2.research.att.com/~bs/C%2B%2B0xFAQ.html#for
Так что без rvalue-ссылок можно обойтись.
Matrix a(b + c);
Где именно будет ждать сама матрица результата, пока конструктор не проинициализируется враппером? Нет, можно, конечно, саму матрицу засунуть в динамическую память и использовать подсчёт ссылок, но это будет очень неэффективно.
Для случая rvalue (а именно ValueWrapper) будет вызываться более быстрый оператор + без лишнего копирования для возвращаемого значения, тк мы используем временную переменную rvalue, которую можно безвозбранно портить, тк она временная и больше никому не нужна. .
Вывод: без RValue&& ссылок, как инструмента оптимизации, можно обойтись.
1) Нужно реализовывать дубликат для каждой операции, каждого метода.
2) Всё равно будет копирование результата в конечную переменную. Практически то же самое было бы и без враппера.
3) При умножении, а не сложении, матриц преимуществ не будет, а недостатки останутся.
Я так и не понял, почему первоначальная не заработала... :(
Хотя вы, наверное, это и сказали.
Спасибо. :)
2) От этого можно как-то уйти? В случае RValue-ссылок такой проблемы разве не будет?
3) Это есть и после введения RValue-ссылок.
2) Конструкторы и присваивания с семантикой move — то, зачем rvalue-ссылки и введены.
3) Для подобного типа достаточно RVO. А вот были бы данные в динамической памяти, была бы выгода от move (и без затрат на счётчик ссылок).
>то, зачем rvalue-ссылки и введены.
А я думал их для оптимизации ввели, а move-семантика - побочный эффект. :-[