Angular 7 - Как работать с двумя разными навигационными панелями в зависимости от размера окна?

Ссылка на rvalue - это тип, который ведет себя так же, как обычный ссылочный X & amp ;, за несколькими исключениями. Наиболее важным является то, что когда дело доходит до разрешения функции перегрузки, lvalues ​​предпочитают ссылки на lvalue старого стиля, тогда как rvalues ​​предпочитают новые ссылки rvalue:

void foo(X& x);  // lvalue reference overload
void foo(X&& x); // rvalue reference overload

X x;
X foobar();

foo(x);        // argument is lvalue: calls foo(X&)
foo(foobar()); // argument is rvalue: calls foo(X&&)

Итак, что такое rvalue? Все, что не является lvalue. Lvalue является выражением, которое относится к ячейке памяти и позволяет нам адресовать адрес этой ячейки памяти через & amp; оператор.

Понятно, во-первых, какие значения выполняются с помощью примера:

 class Sample {
  int *ptr; // large block of memory
  int size;
 public:
  Sample(int sz=0) : ptr{sz != 0 ? new int[sz] : nullptr}, size{sz} 
  {}
  // copy constructor that takes lvalue 
  Sample(const Sample& s) : ptr{s.size != 0 ? new int[s.size] :\
      nullptr}, size{s.size}
  {
     std::cout << "copy constructor called on lvalue\n";
  }

  // move constructor that take rvalue
  Sample(Sample&& s) 
  {  // steal s's resources
     ptr = s.ptr;
     size = s.size;        
     s.ptr = nullptr; // destructive write
     s.size = 0;
     cout << "Move constructor called on rvalue." << std::endl;
  }    
  // normal copy assignment operator taking lvalue
  Sample& operator=(const Sample& s)
  {
   if(this != &s) {
      delete [] ptr; // free current pointer
      ptr = new int[s.size]; 
      size = s.size; 
    }
    cout << "Copy Assignment called on lvalue." << std::endl;
    return *this;
  }    
 // overloaded move assignment operator taking rvalue
 Sample& operator=(Sample&& lhs)
 {
   if(this != &s) {
      delete [] ptr; //don't let ptr be orphaned 
      ptr = lhs.ptr;   //but now "steal" lhs, don't clone it.
      size = lhs.size; 
      lhs.ptr = nullptr; // lhs's new "stolen" state
      lhs.size = 0;
   }
   cout << "Move Assignment called on rvalue" << std::endl;
   return *this;
 }
//...snip
};     

Операторы конструктора и присваивания были перегружены версиями, которые принимают ссылки rvalue. Ссылки Rvalue позволяют функции разветвляться во время компиляции (через разрешение перегрузки) при условии «Я вызываюсь на lvalue или rvalue?». Это позволило нам создать более эффективные операторы конструктора и присваивания выше, чем переместить ресурсы, а скорее скопировать их.

Компилятор автоматически разветвляется во время компиляции (в зависимости от того, будет ли он вызываться для lvalue или rvalue), выберите, нужно ли вызывать конструктор перемещения или оператор назначения перемещения.

Подведение итогов: ссылки rvalue позволяют переносить семантику (и совершенную переадресацию, обсуждаемую в ссылке ниже).

Одним из практических понятных примеров является шаблон класса std :: unique_ptr. Поскольку unique_ptr сохраняет исключительную собственность на свой основной необработанный указатель, unique_ptr не может быть скопирован. Это нарушит их инвариант исключительной собственности. Поэтому у них нет конструкторов копирования. Но у них есть конструкторы перемещения:

template class unique_ptr {
  //...snip
 unique_ptr(unique_ptr&& __u) noexcept; // move constructor
};

 std::unique_ptr ptr2{ptr1};// compile error: no copy ctor.  

 // So we must first cast ptr1 to an rvalue 
 std::unique_ptr ptr2{std::move(ptr1)};  

std::unique_ptr TakeOwnershipAndAlter(std::unique_ptr param,\
 int size)      
{
  for (auto i = 0; i < size; ++i) {
     param[i] += 10;
  }
  return param; // implicitly calls unique_ptr(unique_ptr&&)
}

// Now use function     
unique_ptr ptr{new int[10]};

// first cast ptr from lvalue to rvalue
unique_ptr new_owner = TakeOwnershipAndAlter(\
           static_cast&&>(ptr), 10);

cout << "output:\n";

for(auto i = 0; i< 10; ++i) {
   cout << new_owner[i] << ", ";
}

output:
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 

static_cast&&>(ptr) обычно делается с помощью std :: move

// first cast ptr from lvalue to rvalue
unique_ptr new_owner = TakeOwnershipAndAlter(std::move(ptr),0);

Отличная статья, объясняющая все это и многое другое (например, как rvalues позволяют совершенную переадресацию, и что это означает) с большим количеством хороших примеров - это ссылки на C ++ Rvalue Томаса Беккера . Этот пост в значительной степени опирался на его статью.

Короче введение Краткое введение в Rvalue Ссылки Stroutrup, et. аль

2
задан Thomaz Capra 17 January 2019 в 00:39
поделиться

1 ответ

У меня была похожая проблема. Когда я создавал резюме в Angular, я хотел показать mat-horizontal-stepper, когда экран больше 700 пикселей, и mat-vertical-stepper, когда он меньше его. Поэтому я создал событие с HostListener по window:resize.

Это мое развернутое резюме, если вы измените размер, вы увидите ожидаемое поведение.

Вот как мои HTML с horizontalStepper, в строке 23 вы можете увидеть, что если значение истинно, показать что-то, в противном случае показать что-то еще.

И это файл TS моего компонента, в строке 36 вы можете найти HostListener.

0
ответ дан Thomaz Capra 17 January 2019 в 00:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: