Почему регулярность функциональных процедур позволяет передавать по значению и передавать по постоянной ссылке? - PullRequest
0 голосов
/ 11 марта 2019

В книге «Элементы программирования» Александра А. Степанова и Пола МакДжонс указано:

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

Используя следующее определение из книги

Процедура является регулярной, если и только если замена ее входных данных равными объектами приводит к равным выходным объектам.

Давайте предположим, что существует тип объекта, который представляет логические значения в одном слове, назовем его foolean. 0 интерпретируется как false, а все остальные состояния (1 ... n) интерпретируются как true.

Теперь давайте предположим, что существует процедура, которая принимает значение типа foolean и возвращает его представление в виде строки нулей и единиц.

Эта процедура явно не является регулярной, поскольку можно передать ей много истинных значений, и она будет возвращать различные выходные объекты. Однако я не понимаю, как было бы проблематично передать ему входные данные по значению или константной ссылке (за исключением того факта, что наличие такого типа данных было бы неуместным для начала!).

Что такое регулярность функциональных процедур в отличие от других процедур, которые допускают две техники?

Ответы [ 2 ]

3 голосов
/ 11 марта 2019

Одно свойство обычного типа:

auto a = b;
assert(a==b);

;копии равны.У вас может быть неправильный тип, который не имеет этого свойства;например, == может проверять идентичность, а копирование может создавать отдельную идентичность.

В обычной процедуре у нас есть свойство, что если (a==b), то f(a) и f(b) имеют одинаковыеэффект.

Но f( X const& ) не копирует, а f( X ) делает , копирует.Так что если тип X нерегулярен в том смысле, что копии не равны, то преобразование f( X const& ) в f( X ) может изменить поведение.

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

1 голос
/ 11 марта 2019

Я чувствую, что важная часть есть:

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

На самом деле это хорошая практика для любой функции в C ++.

Передача объектов по значению создает копию в памяти, так что вы действительно не хотите делать это, если объект большой и вам действительно не нужна изменяемая копия, вот когда вы передаете ее по ссылке (которая не создает копию). Обратите внимание, что вы всегда должны предпочитать передачу const ссылок, если вам действительно не нужна изменяемая ссылка (чего не следует делать).

Обычная функция гарантирует, что при создании копии вы не измените поведение.

Кроме того, функция, которую вы описали там (с foolean) , является обычной. Регулярность не означает, что никакие два входа не могут привести к одному и тому же результату. f(1) == f(2) не означает, что f не является регулярным, если f(1) все еще совпадает с f(copy(1)) (что иногда не так).

...