Кто может объяснить, зачем push_back типа void, а не типа ссылки на контейнер? Зачем заставлять меня делать нелепые телодвижения ради возможности писать container.push_back(x).push_back(y).... ? Почему сразу нельзя было?
Эффективность чего? Соптимизировать возврат *this, если он не используется в точке вызова, по-моему, может и ребенок.
pop_* отделено от "peek" по более разумным соображениям эффективности: если бы pop_* возвращал значение, то даже при его неиспользовании вызывать конструктор временной копии все равно надо было бы.
Скорее всего сделано для симметрии с другими подобными функциями: push_front, pop_back, pop_front.
Вдогонку. Хоть формально и не могу объяснить, но интуитивно мне не нравится код вида: container.push_back(x).push_back(y). Как и многие другие тоже отметили. Есть в этом что-то не то. Если речь идёт о генерации кода (каковая сама по себе далеко не мейнстримная задача, заметим), то сгенерить container.push_back(x); container.push_back(y); точно так же легко. Так что этот аргумент я не могу принять.
push_back был ради примера. Вопрос одинаково приложим ко всем четырем.
Даже безотносительно к генерации кода, где может хотеться разделить генерацию объекта и операций над ним, и не протаскивать одно через другое, чем не угодило get_container_ref().push_back(x).push_back(y)?
Не угодило тем что возврат ссылки на контейнер из всего что не оператор = выглядит странно и неуместно. Единственный осмысленный тип, который могли бы возвращать подобные функции, это ссылка/итератор на элемент контейнера, над которым совершается действие. Но некоторые из них не могут возвращать такой тип из-за ограничений накладываемых by exception safety requirements. Поэтому наверное решили привести их всех к общему знаменателю, т.е. void.
Я имею в виду ссылку на себя из других методов контейнера (и просто класса в общем случае). Возвращение ссылки на себя не из операторов и не из специальных методов, типа self() - это скорее Java-изм. Формально, конечно, это не запрещено, но внутреннее чувство прекрасного противится.
Так всё равно заводить переменную для контейнера надо. И к тому же, не следует слепо избегать локальных переменных. Иначе получаются всем известные Жаба-ужасы с 15-ю сцепленными вызовами.
Компилятор выкинет лишние локальные переменные, а вот readability пострадает.
Не надо делать из readability культа. В моем случае сгенерированный код никто, кроме компилятора, не читает, а генератор, из-за того, что push_back - void, оказался несколько сложнее, чем мог бы.
There is a sad obligation to return a reference from the assignment. C introduced the dangerous ability to write a = (b = c). C++ made it so that we can write the even more dangerous (a = b) = c. I would rather live in a world where assignments return void. And while we are forced to make our assignments to conform to the standard semantics, we should avoid using this semantics in our code. (This is similar to Jon Postel’s Robustness Principle: “TCP implementations will follow a general principle of robustness: be conservative in what you do, be liberal in what you accept from others.”)
это не язык а всего лишь стандартная библиотека. При написании STL мнение Степанова, предпочитающего void-ы, очевидно учитывалось. А в стандартную библиотеку оно попало явочным порядком.
я не согласен по всем трем пунктам, и согласен дальше не соглашаться, т.е. я считаю, что стандартная библиотека не часть языка, вкусовщина при выработке стандартов уместна, а фаворитизм неизбежен, особенно в ситуациях когда есть несоменные лидеры индустрии. Это цена прогресса. Лучше застолбить что-то и двигаться вперед, чем придумывать эксперанто.
no subject
Date: 2011-06-07 08:12 pm (UTC)Заведи свой темплит.
no subject
Date: 2011-06-07 08:13 pm (UTC)Шоб неповадно что было?
no subject
Date: 2011-06-07 08:14 pm (UTC)no subject
Date: 2011-06-07 08:17 pm (UTC)no subject
Date: 2011-06-07 08:20 pm (UTC)no subject
Date: 2011-06-07 08:24 pm (UTC)no subject
Date: 2011-06-07 08:23 pm (UTC)no subject
Date: 2011-06-07 08:28 pm (UTC)container.push_back(x); container.push_back(y);
Разница чисто синтаксическая.
no subject
Date: 2011-06-08 12:11 am (UTC)Другое дело, что темная сторона силы может вылезти в каких-нибудь побочных ффектах. Типа
container.push_back(x++).push_back(x++); - это, надо полагать, undefined behavior. А
container.push_back(x++);
container.push_back(x++); - нет.
no subject
Date: 2011-06-08 12:19 am (UTC)Вон, std::cout << x++ << x++; допустимо, и все прекрасно себя чувствуют.
no subject
Date: 2011-06-08 07:50 am (UTC)no subject
Date: 2011-06-08 01:08 am (UTC)no subject
Date: 2011-06-08 01:35 am (UTC)pop_* отделено от "peek" по более разумным соображениям эффективности: если бы pop_* возвращал значение, то даже при его неиспользовании вызывать конструктор временной копии все равно надо было бы.
no subject
Date: 2011-06-08 01:41 pm (UTC)http://ptgmedia.pearsoncmg.com/images/020163371x/supplements/Exception_Handling_Article.html
no subject
Date: 2011-06-08 01:45 pm (UTC)no subject
Date: 2011-06-09 12:41 am (UTC)no subject
Date: 2011-06-08 04:19 am (UTC)Вдогонку. Хоть формально и не могу объяснить, но интуитивно мне не нравится код вида: container.push_back(x).push_back(y). Как и многие другие тоже отметили. Есть в этом что-то не то. Если речь идёт о генерации кода (каковая сама по себе далеко не мейнстримная задача, заметим), то сгенерить container.push_back(x); container.push_back(y); точно так же легко. Так что этот аргумент я не могу принять.
no subject
Date: 2011-06-08 04:50 am (UTC)Даже безотносительно к генерации кода, где может хотеться разделить генерацию объекта и операций над ним, и не протаскивать одно через другое, чем не угодило get_container_ref().push_back(x).push_back(y)?
no subject
Date: 2011-06-08 05:08 am (UTC)no subject
Date: 2011-06-08 05:18 am (UTC)Класс Брюки {
Контейнер левыйКарман, правыйКарман;
Контейнер & болееСвободныйКарман() { ... }
}
no subject
Date: 2011-06-08 05:41 am (UTC)no subject
Date: 2011-06-08 06:06 am (UTC)no subject
Date: 2011-06-08 06:11 am (UTC)Компилятор выкинет лишние локальные переменные, а вот readability пострадает.
no subject
Date: 2011-06-08 06:24 am (UTC)no subject
Date: 2011-06-08 06:33 am (UTC)Итого: вопрос о том почему push_back возвращает void - стилистический. Так решили создатели стандартной библиотеки следую сложившемуся стилю в С++.
no subject
Date: 2011-06-08 07:10 am (UTC)no subject
Date: 2011-06-08 09:15 am (UTC)no subject
Date: 2011-06-08 07:55 am (UTC)Вот цитата из Степанова:
There is a sad obligation to return a reference from the assignment. C introduced the dangerous ability to write a = (b = c). C++ made it so that we can write the even more dangerous (a = b) = c. I would rather live in a world where assignments return void. And while we are forced to make our assignments to conform to the standard semantics, we should avoid using this semantics in our code. (This is similar to Jon Postel’s Robustness Principle: “TCP implementations will follow a general principle of robustness: be conservative in what you do, be liberal in what you accept from others.”)
no subject
Date: 2011-06-08 08:31 am (UTC)Вот именно. Именно поэтому стандарт языка должен быть как можно более либеральным.
no subject
Date: 2011-06-08 08:44 am (UTC)no subject
Date: 2011-06-08 08:53 am (UTC)При написании STL мнение Степанова, предпочитающего void-ы, очевидно учитывалось. А в стандартную библиотеку оно попало явочным порядком.
Во-во. Что есть, мягко говоря, непорядок. При выработке стандартов не должно быть вкусовщины и фаворитизма.
no subject
Date: 2011-06-08 09:14 am (UTC)no subject
Date: 2011-06-08 06:51 am (UTC)no subject
Date: 2011-06-08 07:11 am (UTC)no subject
Date: 2011-06-08 07:55 am (UTC)no subject
Date: 2011-06-08 06:27 pm (UTC)That's why.
They don't care about you.
API designers are a special kind of assholes. They are happy to make you jump through the loops.
no subject
Date: 2011-06-08 06:32 pm (UTC)no subject
Date: 2011-06-09 06:57 am (UTC)Впрочем, именно это ты и сделал... А вообще - да, иной раз такие вещи сильно раздражают.