Сконфигурируйте ssh для Jenkins внутри Docker

Он объявляет ссылку rvalue (doc стандартного предложения).

Вот введение в rvalue ссылки .

Вот фантастический глубокий взгляд на ссылки rvalue одним из разработчиков стандартной библиотеки Microsoft . (Но см. Предупреждение в комментариях, следующих за этим ответом, перед тем, как прочитать эту статью.)

Самое большое различие между ссылкой C ++ 03 (теперь называемой ссылкой lvalue в C ++ 11) заключается в том, что она может привязать к rvalue как временный, не будучи const. Таким образом, этот синтаксис теперь легален:

T&& r = T();

Ссылки rvalue в первую очередь предусматривают следующее:

Переместить семантику. Оператор присваивания шага конструктора и двигаться теперь может быть определен, что принимает ссылку RValue вместо обычного сопзЬ-именующей ссылки. Движение функционирует подобно копиям, за исключением того, что он не обязан сохранять исходный код без изменений; на самом деле, он обычно изменяет источник таким образом, что он больше не владеет перемещенными ресурсами. Это замечательно для устранения посторонних копий, особенно в стандартных реализациях библиотек.

Например, конструктор копирования может выглядеть так:

foo(foo const& other)
{
    this->length = other.length;
    this->ptr = new int[other.length];
    copy(other.ptr, other.ptr + other.length, this->ptr);
}

Если этот конструктор был передан временным, копия была бы ненужной, потому что мы знаем, что временное будет просто уничтожено; почему бы не использовать ресурсы, выделенные временным образом? В C ++ 03 невозможно предотвратить копирование, поскольку мы не можем определить, что мы прошли временный. В C ++ 11 мы можем перегрузить конструктор перемещения:

foo(foo&& other)
{
   this->length = other.length;
   this->ptr = other.ptr;
   other.length = 0;
   other.ptr = nullptr;
}

Обратите внимание на большую разницу здесь: конструктор перемещения фактически модифицирует свой аргумент. Это эффективно «переместило» временное в построенный объект, тем самым устранив ненужную копию.

Конструктор перемещения будет использоваться для временных и неконсольных ссылок lvalue, которые явно преобразуются в rvalue-ссылки, используя std::move (он просто выполняет преобразование). Следующий код вызывает как конструктор перемещения для f1 и f2:

foo f1((foo())); // Move a temporary into f1; temporary becomes "empty"
foo f2 = std::move(f1); // Move f1 into f2; f1 is now "empty"

Совершенная пересылка. Ссылки rvalue позволяют нам правильно пересылать аргументы для шаблонных функций. Возьмем, к примеру, эту заводскую функцию:

template 
std::unique_ptr factory(A1& a1)
{
    return std::unique_ptr(new T(a1));
}

Если мы назовем factory(5), аргумент будет выведен как int&, который не будет связываться с литералом 5, даже если foo ' s конструктор принимает значение int. Ну, мы могли бы вместо этого использовать A1 const&, но что, если foo принимает аргумент конструктора посредством ссылки не const? Чтобы сделать действительно общую заводскую функцию, нам пришлось бы перегружать завод на A1& и на A1 const&. Это может быть хорошо, если фабрика принимает один тип параметра, но каждый дополнительный тип параметра будет умножать необходимую перегрузку, установленную на 2. Это очень быстро недостижимо.

Ссылки rvalue исправляют эту проблему, позволяя стандартной библиотеке определять std::forward, которая может правильно пересылать ссылки lvalue / rvalue. Для получения дополнительной информации о работе std::forward см. этот отличный ответ .

Это позволяет нам определить заводскую функцию следующим образом:

template 
std::unique_ptr factory(A1&& a1)
{
    return std::unique_ptr(new T(std::forward(a1)));
}

Теперь значение rvalue / lvalue-n аргумента сохраняется при передаче в конструктор T. Это означает, что если фабрика вызывается с rvalue, конструктор T вызывается с rvalue. Если фабрика вызывается с lvalue, конструктор T вызывается с lvalue. Улучшенная заводская функция работает из-за одного специального правила:

Когда тип параметра функции имеет форму T&&, где T является параметром шаблона, а аргумент функции - значением l type A, тип A& используется для вывода аргумента шаблона.

blockquote>

Таким образом, мы можем использовать заводскую настройку следующим образом:

auto p1 = factory(foo()); // calls foo(foo&&)
auto p2 = factory(*p1);   // calls foo(foo const&)

Важная ссылка rvalue Свойства:

  • Для разрешения перегрузки lvalues ​​предпочитают привязку к lvalue-ссылкам, а rvalues ​​предпочитают привязывать к rvalue-ссылкам. Поэтому почему временные пользователи предпочитают ссылаться на оператор присваивания move / move для оператора компоновки / назначения экземпляра.
  • Ссылки rvalue будут неявно связываться с rvalues ​​и временными, которые являются результатом неявного преобразования. то есть float f = 0f; int&& i = f; хорошо сформирован, поскольку float неявно конвертируется в int; ссылка будет заключаться в временном результате, являющемся результатом преобразования.
  • Именованные ссылки rvalue являются lvalues. Без названия ссылки rvalues. Важно понять, почему вызов std::move необходим в: foo&& r = foo(); foo f = std::move(r);

1
задан N. D 16 January 2019 в 21:57
поделиться