использование boost :: ref для передачи ссылки на функции, принимающие значения

Я запутался в использовании boost :: ref. Я не понимаю, почему кто-то хотел бы сделать следующее —

void f(int x)
{
cout << x<<endl;
x++;
}

int main(int argc, char *argv[])
{
int aaa=2;
f(boost::ref(aaa));
cout << aaa<<endl;
exit(0);
}

Какая польза от передачи ссылки в функцию. Я всегда могу передать по значению вместо этого. Также это не то, что ссылка фактически передана. Выше значение aaa в основном остается только 2.

Где именно Boost Ref полезен?

Можно ли использовать boost :: ref в этом сценарии.
Я хочу передать ссылку на итератор в функцию std :: sort. обычно сортировка работает на копиях итераторов — boost :: ref заставит его работать и для ссылок? (без каких-либо изменений в std :: sort)

2

Решение

Я не понимаю, почему кто-то хотел бы сделать следующее

Они не будут. Это не то boost::ref (или в эти дни std::ref) для. Если функция принимает аргумент по значению, то нет способа заставить его взять его по ссылке.

Где именно Boost Ref полезен?

Может использоваться для создания функции шаблон действовать так, как будто он принимает аргумент по ссылке, создавая экземпляр шаблона для ссылочного типа (обертки), а не типа значения:

template <typename T>
void f(T x) {++x;}

f(aaa);      cout << aaa << endl; // increments a copy: prints 0
f(ref(aaa)); cout << aaa << endl; // increments "a" itself: prints 1

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

void f(int & x) {++x;}

int aaa = 0;
auto byval = bind(f, aaa);      // binds a copy
auto byref = bind(f, ref(aaa)); // binds a reference

byval(); cout << aaa << endl;   // increments a copy: prints 0
byref(); cout << aaa << endl;   // increments "a" itself: prints 1

Можно ли использовать boost:; ref в этом сценарии. Я хочу передать ссылку на итератор в функцию std :: sort. обычно сортировка работает на копиях итераторов — boost :: ref заставит его работать и для ссылок?

Нет; ссылочная оболочка не соответствует требованиям итератора, поэтому ее нельзя использовать в стандартных алгоритмах. Если бы вы могли, то многие алгоритмы пошли бы ужасно неправильно, если бы им нужно было делать независимые копии итераторов (столько, сколько большинство sort реализации, должны сделать).

13

Другие решения

Вы читали документация?

Это говорит:

Библиотека Ref — это небольшая библиотека, которая полезна для передачи ссылок на шаблоны функций (алгоритмы), которые обычно принимают копии своих аргументов.

В вашем первом примере void f(int) не шаблон функции, поэтому нет никакого эффекта: анонимный временный boost::reference_wrapper<int> создается и немедленно преобразуется обратно в int& который затем разыменовывается, чтобы передать int к вашей функции. Надеюсь, компилятор отбросит всю эту чепуху, поскольку она не имеет никакого эффекта.

Ты говоришь:

… Я всегда могу передать по значению вместо этого.

это правда, но они делают разные вещи. Передача по ссылке:

  • избегает копирования, что, вероятно, бессмысленно для целых чисел, но полезно для больших или дорогих для копирования объектов
  • позволяет вызывающей стороне видеть, что называется вызываемой функцией сделал со своим аргументом. Это вряд ли будет полезно для std::sort, но в общем случае использование параметров ввода-вывода может быть полезным

Это может разрешать std::sort действовать по ссылкам на итераторы, избегая копирования (хотя в любом случае итераторы обычно бывают дешевыми для копирования типами значений), но я этого не пробовал. Если вы думаете, что это поможет вам, почему бы не попробовать и посмотреть?

-1