Является ли std :: reference_wrapper похожим на ссылку python pass-by-object?

Изучая Python, я читал, что:

Аргументы не являются ни “passed-by-reference“ ни “passed-by-value“ . Они “passed-by-object-reference” .

Я пытаюсь понять и сравнить это с точки зрения C ++.

Является ли поведение передаваемых аргументов в Python таким же, как передача аргументов как std::reference_wrapper s в C ++?


Справедлива ли эта аналогия с точки зрения поведения и предполагаемых случаев использования?

Короткий ответ: Нет, std::reference_wrapper<T> не делает этого, потому что различия между C ++ и Python (на практике) – это такие вопросы, как «что происходит в куче» и «какие типы неизменяемы».

В Python все идет в кучу. Числа, строки и указатели неизменяемы. У вас нет указателей на переменные. Python – это пропускная способность, как почти каждый современный язык.

В C ++ вы выбираете, что происходит в куче. Почти все может быть изменено. У вас могут быть указатели на переменные, указатели на внутренние объекты, и вы можете передавать большие структуры данных, копируя их. C ++ – это, в основном, пропускная способность, как почти каждый современный язык, за исключением того, что вы можете пометить некоторые параметры как переданные по ссылке.

Пропускайте, черт возьми!

Честно говоря, люди делают это сложнее, чем есть на самом деле. Проблема с простое высказывание «pass-by-value» или «pass-by-reference» заключается в том, что наше интуитивное понимание «значения» и «ссылки» не соответствует техническому способу их использования здесь.

Вот явное свидетельство того, что Python имеет значение pass-by-value:

 def func(x): x = [4, 5, 5] def func2(): y = [1, 2, 3] func(y) print(y) # prints [1, 2, 3] 

Запутанная часть состоит в том, что новичок подумает, что значение [1, 2, 3] является значением, но опытный пользователь Python поймет, что [1, 2, 3] – это содержимое объекта, а указатель на этот объект затем передается (по значению) функции. Здесь начинаются новички:

 def func(x): x[:] = [4, 5, 6] def func2(): y = [1, 2, 3] func(y) print(y) # prints [4, 5, 6] 

Я думаю, что это явное доказательство того, что x и y являются указателями на один и тот же объект. Мы знаем, что x не является ссылкой на y , так как присвоение нового значения x не влияет на y . Он работает так же, как и в C, но по какой-то причине люди менее запутаны.

 void func(int *x) { x[0] = 4; x[1] = 5; x[2] = 6; } void func2() { int y[3] = {1, 2, 3}; func(y); printf("%d, %d, %d\n", y[0], y[1], y[2]); } 

То же самое обсуждается в сообществе Java с тем же самым заключением. В Java переменные с типом объекта содержат указатели. Эти указатели передаются по значению. Функции Java передаются по значению. См. Java – это пропускная способность, проклятье! или Ява «pass-by-reference» или «pass-by-value»?

«Pass-by-object-value» – лишний термин для людей, которые не понимают, что такое указатели, и считают, что Python не имеет указателей, потому что вместо этого он называет их «ссылками». Java проделала здравый смысл и фактически назвала их указателями в спецификации Java.

Другая запутанная часть о Python – это объекты, подобные 6.28 или "Hello, World!" являются неизменными, вы не можете сказать разницу между передачей содержимого объекта по значению и передачей указателя по значению. (И CPython – это только одна реализация.)

Что такое std::reference_wrapper<T> для?

Единственное, что происходит здесь, это то, что C ++ имеет два типа указателей. Некоторые указатели называются «указателями», а некоторые называются «ссылками». Они – одна и та же базовая концепция, выраженная по-разному. Цель std::reference_wrapper<T> состоит в том, чтобы сделать что-то, что похоже на ссылку C ++, но может быть переназначено. Или, если хотите, что-то похожее на указатель C ++, но не может быть NULL. В конце концов, он по-прежнему концептуально является указателем, даже если вы называете его ссылкой. Или это по-прежнему концептуально ссылка, даже если она не ведет себя точно так же, как T& .

Точно так же, как в Python или Java, где у вас есть указатели на объекты, даже если вы решили назвать их ссылками.