Здравствуйте, rusted, Вы писали:
R>Здравствуйте, andyag, Вы писали:
A>>>>В 2014 году гнобить C++ — это как смеяться над инвалидом, что тот не может ходить: всем очевидно, но смешного ничего нет. CC>>>Отчего же. Смешно то, что в 2014м году до сих пор старательно псят на С++, а караван тем не менее продолжает идти.
A>>...нагавногу. Глупо спорить, что он _есть_. Но есть он не потому, что живёт и развивается, а просто потому что его на пике было очень много и всё никак не рассосётся.
R>Так на пике его было очень много как раз потому, что все остальные претенденты на инвалидное кресло C++ оказывались еще большими калеками. Да и сейчас во многих областях применения альтернатив так и не появилось.
Так я ж и не спорю. Когда-то были такие времена, да.
Здравствуйте, D. Mon, Вы писали:
DM>Шедевральное и очень веселое выступление одного из корифеев С++ о том, как много там косяков, несуразностей и ненужных сложностей прямо со входа: DM>http://www.ustream.tv/recorded/47947981
Интересно, кто из комментаторов удосужился таки посмотреть видео. Оно дельное, интересное, но не холиварное.
Здравствуйте, Константин, Вы писали:
К>Интересно, кто из комментаторов удосужился таки посмотреть видео. Оно дельное, интересное, но не холиварное.
Посмотрел. В секции про STL практически всё не по делу, такое впечатление что он готовился спустя рукава:
* Сложность binary_search — в стандарте написано чётко "Complexity: At most log2(last — first) + O(1) comparisons" то есть тут Майерс придирается не по делу;
* binary_search возвращает bool, а не итератор как у него;
* в C++11 std::sort O(N logN), а не квадратичная;
* erase vs remove — там действительно нужны разные имена
, и всё вполне консистентно;
Замечание про list::stable_sort более-менее адекватное, и то думаю можно поспорить (вспоминается что Степанов говорил в своих лекциях
А в общем, да — можно найти вагон и маленькую тележку мест которые можно было бы радикально упростить, если не оглядываться на обратную совместимость. Тут больше всего подходит следующее высказывание Страуструпа:
There are only two kinds of languages: the ones people complain about and the ones nobody uses.
И да, было бы неплохо если бы был современный и мощный язык, с теми же фундаментальными design principles — а именно, с той же приверженностью к производительности — тогда можно было бы говорить о приемнике (или какой там термин более подходящий). Но вот что-то ничего не видно на горизонте
Например, авторы того же D, явно говорят в одном из своих интервью, что готовы жертвовать производительностью ради других benefits. Я бы даже сказал, что D это скорее альтернатива C#/Java/Objective-C, чем C++.
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Здравствуйте, Константин, Вы писали:
К>>Интересно, кто из комментаторов удосужился таки посмотреть видео. Оно дельное, интересное, но не холиварное.
EP>Посмотрел. В секции про STL практически всё не по делу, такое впечатление что он готовился спустя рукава: EP>* Сложность binary_search — в стандарте написано чётко "Complexity: At most log2(last — first) + O(1) comparisons" то есть тут Майерс придирается не по делу; EP>* binary_search возвращает bool, а не итератор как у него; EP>* в C++11 std::sort O(N logN), а не квадратичная; EP>* erase vs remove — там действительно нужны разные имена
Да плохие имена, чего уж тут говорить.
Я вот старый уже совсем ни не помню, какие имена за что отвечают, если честно.
Вот было бы move_to_back вместо remove — и не было бы проблем.
binary_search — то же самое. Вообще непонятно, нафига нужна эта функция, когда нет никаких проблем сравнить итератор с last. Я тоже постоянно эту ошибку совершаю, потому что ну нелогично — если ищешь, так, наверное ж, хочешь итератор на то, что нашлось же (я знаю про lower_bound).
Про std::sort — я не помню, он говорил про С++11 или про С++03 — вроде в 03 (или вообще в 98) не было такого ограничения, т.е. был возможен квиксорт с его наихудщим квадратичным случаем. Но реально всегда интросорт используется во всех современных реализациях STL, так что это устарело на практике сто лет как.
В целом ничего нового (для меня), кроме пары моментов с лямбдой, он не сказал.
Но цель его спича и не была в том, чтобы сказать что-то новое о С++ (или вообще говорить о С++).
Цель он изложил в своих заключительных словах, и обращены они, как и весь спич, как разработчикам D — делайте язык как можно более логичным и простым и самосогласованным, чтоб не нужно было никаких майерсов и саттеров с книжками, разъясняющими неочевидности и тонкости, как это нужно в С++ с его 30-летней историей.
За мир во всем мире, в общем.
Здравствуйте, jazzer, Вы писали:
... J>В целом ничего нового (для меня), кроме пары моментов с лямбдой, он не сказал. J>Но цель его спича и не была в том, чтобы сказать что-то новое о С++ (или вообще говорить о С++).
J>Цель он изложил в своих заключительных словах, и обращены они, как и весь спич, как разработчикам D — делайте язык как можно более логичным и простым и самосогласованным, чтоб не нужно было никаких майерсов и саттеров с книжками, разъясняющими неочевидности и тонкости, как это нужно в С++ с его 30-летней историей. J>За мир во всем мире, в общем.
И что снова опять наново D №3 ?
Здравствуйте, jazzer, Вы писали:
J>Я вот старый уже совсем ни не помню, какие имена за что отвечают, если честно. J>Вот было бы move_to_back вместо remove — и не было бы проблем.
Ты видимо имеешь в виду std::remove (отдельный алгоритм), а не обсуждаемый std::list::remove.
J>binary_search — то же самое. Вообще непонятно, нафига нужна эта функция, когда нет никаких проблем сравнить итератор с last. Я тоже постоянно эту ошибку совершаю, потому что ну нелогично — если ищешь, так, наверное ж, хочешь итератор на то, что нашлось же (я знаю про lower_bound).
Проверки с last недостаточно — lower_bound может вернуть итератор на внутренний элемент, который не равен данному.
Для тех случаев, когда нужен конкретный элемент, у меня есть алгоритм binary_find возвращающий optional (хотя можно и просто итератор/указатель).
А про binary_search Степанов рассказывал в своих видеолекциях, вот ссылка на конкретный момент:
And, now there is an embarrassing function. So, I worked on STL, and if you remember — there was a [...], they threw a lot of useful functions. But then they inserted some functions, very few. And one of them was a function called binary_search.
There was an conversation, when my opposite number, let him [don't name] since he was a very good friend of mine. So this opposite number, says "but where is binary search?". And I say "well, there is upper_bound, lower_bound, [...] equal_range". But he says "where is binary search?" — "That is binary_search" — "No, no, we need binary search".
So, I say "what kind of interface would you like?", "Oh, like normal binary search interface: you give it a range, and an element, and it true or false".
Whether it is there or not? There is a function like that in STL. Who would argue with the best friend.
Have I ever used it? No.
[...]
I have to say something about standardization, I have scars all over my body, so I earned it. This is why I wear long pants and shirt
J>Про std::sort — я не помню, он говорил про С++11 или про С++03 — вроде в 03 (или вообще в 98) не было такого ограничения, т.е. был возможен квиксорт с его наихудщим квадратичным случаем.
Да, до C++11 не было такого ограничения, там был просто average.
Но в том то и дело, что во всех этих слайдах он говорит про C++11: auto, unordered_map, forward_list. Поэтому не упоминание про гарантированный O(N logN) в C++11 является очевидным недосмотром.
J>Цель он изложил в своих заключительных словах, и обращены они, как и весь спич, как разработчикам D — делайте язык как можно более логичным и простым и самосогласованным, чтоб не нужно было никаких майерсов и саттеров с книжками, разъясняющими неочевидности и тонкости, как это нужно в С++ с его 30-летней историей. J>За мир во всем мире, в общем.
Это всё понятно, и я с этим согласен. И, как уже сказал выше, в C++ таких мест вагон и маленькая тележка.
Просто большинство примеров про STL которые он показал — далеко не самые удачные, и такое впечатление что он их выискивал спустя рукава. Мог бы, например, показать ошибку в интерфейсе у std::copy_n.
Здравствуйте, Evgeny.Panasyuk, Вы писали:
J>>За мир во всем мире, в общем.
EP>Это всё понятно, и я с этим согласен. И, как уже сказал выше, в C++ таких мест вагон и маленькая тележка. EP>Просто большинство примеров про STL которые он показал — далеко не самые удачные, и такое впечатление что он их выискивал спустя рукава. Мог бы, например, показать ошибку в интерфейсе у std::copy_n.
В этом плане довольно прикольная багофича была, что std::lower_bound принимает функтор от (*It, val) а std::upper_bound(Val, *it). Наверняка кто нибудь придумает оправдание почему это так, но выглядит прикольно.
Здравствуйте, denisko, Вы писали:
D>В этом плане довольно прикольная багофича была, что std::lower_bound принимает функтор от (*It, val) а std::upper_bound(Val, *it). Наверняка кто нибудь придумает оправдание почему это так, но выглядит прикольно.
Всё правильно. Например, есть бинарный предикат less, опорное значение pivot, и некоторое значение x.
Чтобы проверить x < pivot, нужно вызвать less(x, pivot).
Чтобы проверить x <= pivot, нужно вызвать !less(pivot, x).
lower_bound разделяет range на два — в одном все значения меньше [first, lower_bound), а во втором не меньше заданного [lower_bound, last).
upper_bound разделяет range на два — в одном все значения не больше [first, upper_bound), а во втором больше заданного [upper_bound, last).
Или другой пример: имея только бинарный предикат less и std::partition_point (тот же самый бинарный поиск), реализовать lower_bound и upper_bound.
Здравствуйте, denisko, Вы писали:
D>В этом плане довольно прикольная багофича была, что std::lower_bound принимает функтор от (*It, val) а std::upper_bound(Val, *it). Наверняка кто нибудь придумает оправдание почему это так, но выглядит прикольно.
если б у функтора в upper_bound была бы сигнатура (*It, val) , то тогда в этот алгоритм нельзя было передовать тот функтор, которым сортировали контейнер.
template <typename It, typename T, typename Comp>
It my_upper_bound(It first, It last, const T& val, Comp comp)
{
using namespace std::placeholders;
return upper_bound(first, last, val, std::bind(comp, _2, _1));
}
int main()
{
vector<int> v{5,2,3,1,4};
auto compare = greater<int>();
sort(v.begin(), v.end(), compare);
auto std_upper = upper_bound(v.begin(), v.end(), v[1], compare);
cout << "std::upper_bound = " << std_upper - v.begin() << endl;// 2, как и ожидалосьauto my_upper = my_upper_bound(v.begin(), v.end(), v[1], compare);
cout << "my_upper_bound = " << my_upper - v.begin() << endl; // 5??? WTF ?return 0;
}
Здравствуйте, D. Mon, Вы писали:
DM>Шедевральное и очень веселое выступление одного из корифеев С++ о том, как много там косяков, несуразностей и ненужных сложностей прямо со входа: DM>http://www.ustream.tv/recorded/47947981
The "best" example of this maintainability problem could be found in the old implementation of the printf family of functions. The CRT provides 142 different variations of printf, but most of the behavior is the same for all of the functions, so there are a set of common implementation functions that do the bulk of the work. These common implementation functions were all defined in output.c in the CRT sources(1). This 2,696 line file had 223 conditionally compiled regions of code (#ifdef, #else, etc.), over half of which were in a single 1,400 line function. This file was compiled 12 different ways to generate all of the common implementation functions.
Пургу гонит.
Не инициализирован int по умолчанию, причем здесь C++. Например, Borland компиляторы по умолчанию инициализировали нулем.
Зачем эта хрень с auto?
Понятно дело, что нормальные люди их используют только чтобы избежать длинные шаблонные типа, а не все подряд и везде объявлять auto.
Здравствуйте, HolyNick, Вы писали:
HN>Не инициализирован int по умолчанию, причем здесь C++. Например, Borland компиляторы по умолчанию инициализировали нулем.
Если эта самодеятельность не отражена в стандарте или даже противоречит ему, то это проблема борланда. Причем здесь С++ только?