?

Log in

No account? Create an account

Программистское - Общество дровосеков Бердичева по изучению Мишны

Jun. 7th, 2011

12:54 pm - Программистское

Previous Entry Share Next Entry



Кто может объяснить, зачем push_back типа void, а не типа ссылки на контейнер? Зачем заставлять меня делать нелепые телодвижения ради возможности писать container.push_back(x).push_back(y).... ? Почему сразу нельзя было?

Comments:

[User Picture]
From:dvv
Date:June 7th, 2011 08:12 pm (UTC)
(Link)
Шоб неповадно было.
Заведи свой темплит.
(Reply) (Thread)
[User Picture]
From:spamsink
Date:June 7th, 2011 08:13 pm (UTC)
(Link)
Уже завел.
Шоб неповадно что было?
(Reply) (Parent) (Thread)
[User Picture]
From:dvv
Date:June 7th, 2011 08:14 pm (UTC)
(Link)
Такие колбасы писать.
(Reply) (Parent) (Thread)
[User Picture]
From:spamsink
Date:June 7th, 2011 08:17 pm (UTC)
(Link)
Видишь ли, Юра... Программы иногда порождаются автоматически или полуавтоматически.
(Reply) (Parent) (Thread)
[User Picture]
From:dvv
Date:June 7th, 2011 08:20 pm (UTC)
(Link)
Автомат чинить надо. Или его половину.
(Reply) (Parent) (Thread)
[User Picture]
From:spamsink
Date:June 7th, 2011 08:24 pm (UTC)
(Link)
Зачем его чинить? Той части автомата, которая хочет вставлять, не должно быть дела, куда вставлять.
(Reply) (Parent) (Thread)
From:rezkiy
Date:June 7th, 2011 08:23 pm (UTC)
(Link)
возможность писать container.push_back(x).push_back(y) -- путь на темную сторону силы. Вот бросила эта штука исключение, сколько элементов в листе?
(Reply) (Thread)
[User Picture]
From:spamsink
Date:June 7th, 2011 08:28 pm (UTC)
(Link)
Эта штука семантически не отличается от
container.push_back(x); container.push_back(y);
Разница чисто синтаксическая.
(Reply) (Parent) (Thread)
[User Picture]
From:yatur
Date:June 8th, 2011 12:11 am (UTC)
(Link)
А на светлой стороне силы вокруг каждого оператора try-catch стоит?

Другое дело, что темная сторона силы может вылезти в каких-нибудь побочных ффектах. Типа

container.push_back(x++).push_back(x++); - это, надо полагать, undefined behavior. А

container.push_back(x++);
container.push_back(x++); - нет.


(Reply) (Parent) (Thread)
[User Picture]
From:spamsink
Date:June 8th, 2011 12:19 am (UTC)
(Link)
Ну мало ли можно придумать вариантов с undefined behavior?
Вон, std::cout << x++ << x++; допустимо, и все прекрасно себя чувствуют.
(Reply) (Parent) (Thread)
From:rezkiy
Date:June 8th, 2011 07:50 am (UTC)
(Link)
это не единственный путь на темную сторону силы. А try-catch вокруг _каждого_ оператора -- явный признак неудачно выбранного языка программирования.
(Reply) (Parent) (Thread)
[User Picture]
From:sab123
Date:June 8th, 2011 01:08 am (UTC)
(Link)
Они таким образом борются за эффективность. Из тех же соображений разделены front() и pop_front().
(Reply) (Thread)
[User Picture]
From:spamsink
Date:June 8th, 2011 01:35 am (UTC)
(Link)
Эффективность чего? Соптимизировать возврат *this, если он не используется в точке вызова, по-моему, может и ребенок.

pop_* отделено от "peek" по более разумным соображениям эффективности: если бы pop_* возвращал значение, то даже при его неиспользовании вызывать конструктор временной копии все равно надо было бы.
(Reply) (Parent) (Thread)
[User Picture]
From:Anatoly Borodin
Date:June 8th, 2011 01:45 pm (UTC)
(Link)
Вот ссылка получше: accu.org/index.php/journals/444
(Reply) (Parent) (Thread)
[User Picture]
From:sab123
Date:June 9th, 2011 12:41 am (UTC)
(Link)
В-общем, мораль: от исключений никакой пользы помимо вреда.
(Reply) (Parent) (Thread)
[User Picture]
From:ak_47
Date:June 8th, 2011 04:19 am (UTC)
(Link)
Скорее всего сделано для симметрии с другими подобными функциями: push_front, pop_back, pop_front.

Вдогонку. Хоть формально и не могу объяснить, но интуитивно мне не нравится код вида: container.push_back(x).push_back(y). Как и многие другие тоже отметили. Есть в этом что-то не то. Если речь идёт о генерации кода (каковая сама по себе далеко не мейнстримная задача, заметим), то сгенерить container.push_back(x); container.push_back(y); точно так же легко. Так что этот аргумент я не могу принять.
(Reply) (Thread)
[User Picture]
From:spamsink
Date:June 8th, 2011 04:50 am (UTC)
(Link)
push_back был ради примера. Вопрос одинаково приложим ко всем четырем.

Даже безотносительно к генерации кода, где может хотеться разделить генерацию объекта и операций над ним, и не протаскивать одно через другое, чем не угодило get_container_ref().push_back(x).push_back(y)?
(Reply) (Parent) (Thread)
[User Picture]
From:ak_47
Date:June 8th, 2011 05:08 am (UTC)
(Link)
Не угодило тем что возврат ссылки на контейнер из всего что не оператор = выглядит странно и неуместно. Единственный осмысленный тип, который могли бы возвращать подобные функции, это ссылка/итератор на элемент контейнера, над которым совершается действие. Но некоторые из них не могут возвращать такой тип из-за ограничений накладываемых by exception safety requirements. Поэтому наверное решили привести их всех к общему знаменателю, т.е. void.
(Reply) (Parent) (Thread)
[User Picture]
From:spamsink
Date:June 8th, 2011 05:18 am (UTC)
(Link)
Это еще почему?

Класс Брюки {
Контейнер левыйКарман, правыйКарман;
Контейнер & болееСвободныйКарман() { ... }
}
(Reply) (Parent) (Thread)
[User Picture]
From:ak_47
Date:June 8th, 2011 05:41 am (UTC)
(Link)
Я имею в виду ссылку на себя из других методов контейнера (и просто класса в общем случае). Возвращение ссылки на себя не из операторов и не из специальных методов, типа self() - это скорее Java-изм. Формально, конечно, это не запрещено, но внутреннее чувство прекрасного противится.
(Reply) (Parent) (Thread)
[User Picture]
From:spamsink
Date:June 8th, 2011 06:06 am (UTC)
(Link)
По мне так наоборот: если можно избежать заведения дополнительных переменных, то это и нужно делать.
(Reply) (Parent) (Thread)
[User Picture]
From:ak_47
Date:June 8th, 2011 06:11 am (UTC)
(Link)
Так всё равно заводить переменную для контейнера надо. И к тому же, не следует слепо избегать локальных переменных. Иначе получаются всем известные Жаба-ужасы с 15-ю сцепленными вызовами.

Компилятор выкинет лишние локальные переменные, а вот readability пострадает.
(Reply) (Parent) (Thread)
[User Picture]
From:spamsink
Date:June 8th, 2011 06:24 am (UTC)
(Link)
Не надо делать из readability культа. В моем случае сгенерированный код никто, кроме компилятора, не читает, а генератор, из-за того, что push_back - void, оказался несколько сложнее, чем мог бы.
(Reply) (Parent) (Thread)
[User Picture]
From:ak_47
Date:June 8th, 2011 06:33 am (UTC)
(Link)
Readability - хороший культ. От него пользы больше чем вреда. А про генерацию - так это и есть довольно маргинальная задача.

Итого: вопрос о том почему push_back возвращает void - стилистический. Так решили создатели стандартной библиотеки следую сложившемуся стилю в С++.
(Reply) (Parent) (Thread)
[User Picture]
From:spamsink
Date:June 8th, 2011 07:10 am (UTC)
(Link)
Стандарт языка или его библиотеки не должен форсировать стиль, это унизительно по отношению к пользователям.
(Reply) (Parent) (Thread)
From:rezkiy
Date:June 8th, 2011 09:15 am (UTC)
(Link)
Работать не унизительно :-)
(Reply) (Parent) (Thread)
From:rezkiy
Date:June 8th, 2011 07:55 am (UTC)
(Link)
+1

Вот цитата из Степанова:

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.”)
(Reply) (Parent) (Thread)
[User Picture]
From:spamsink
Date:June 8th, 2011 08:31 am (UTC)
(Link)
"be liberal in what you accept from others"

Вот именно. Именно поэтому стандарт языка должен быть как можно более либеральным.
(Reply) (Parent) (Thread)
From:rezkiy
Date:June 8th, 2011 08:44 am (UTC)
(Link)
это не язык а всего лишь стандартная библиотека. При написании STL мнение Степанова, предпочитающего void-ы, очевидно учитывалось. А в стандартную библиотеку оно попало явочным порядком.
(Reply) (Parent) (Thread)
[User Picture]
From:spamsink
Date:June 8th, 2011 08:53 am (UTC)
(Link)
Всё, что в LRM, есть часть языка.

При написании STL мнение Степанова, предпочитающего void-ы, очевидно учитывалось. А в стандартную библиотеку оно попало явочным порядком.

Во-во. Что есть, мягко говоря, непорядок. При выработке стандартов не должно быть вкусовщины и фаворитизма.
(Reply) (Parent) (Thread)
From:rezkiy
Date:June 8th, 2011 09:14 am (UTC)
(Link)
я не согласен по всем трем пунктам, и согласен дальше не соглашаться, т.е. я считаю, что стандартная библиотека не часть языка, вкусовщина при выработке стандартов уместна, а фаворитизм неизбежен, особенно в ситуациях когда есть несоменные лидеры индустрии. Это цена прогресса. Лучше застолбить что-то и двигаться вперед, чем придумывать эксперанто.
(Reply) (Parent) (Thread)
[User Picture]
From:malaya_zemlya
Date:June 8th, 2011 06:51 am (UTC)
(Link)
Чтобы кто не подумал, что программирует на джаве.
(Reply) (Thread)
[User Picture]
From:spamsink
Date:June 8th, 2011 07:11 am (UTC)
(Link)
Я на ней никогда не программировал, поэтому точно не подумаю.
(Reply) (Parent) (Thread)
[User Picture]
From:_navi_
Date:June 8th, 2011 07:55 am (UTC)
(Link)
скорее, на хаскелле, тогда уж
(Reply) (Parent) (Thread)
[User Picture]
From:juan_gandhi
Date:June 8th, 2011 06:27 pm (UTC)
(Link)
Because most of the programmers are assholes.

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.
(Reply) (Thread)
[User Picture]
From:spamsink
Date:June 8th, 2011 06:32 pm (UTC)
(Link)
Thank you!
(Reply) (Parent) (Thread)
[User Picture]
From:boris71
Date:June 9th, 2011 06:57 am (UTC)
(Link)
Use the source, Luke...

Впрочем, именно это ты и сделал... А вообще - да, иной раз такие вещи сильно раздражают.
(Reply) (Thread)