Учитывая объявление, `std :: unique <T>p;`, почему `! P` является законным, поскольку не существует функции памяти 'operator! ()' Для` std :: unique <T>` - PullRequest
0 голосов
/ 26 мая 2020

Как показано в приведенном ниже коде, я не мог понять, почему !p является законным, поскольку для std::unique<T> нет функции-члена 'operator! ()'.

Поскольку std::cout << p.get() << std::endl; является законным, я думаю p - это объект, а не указатель, поэтому я запутался.

Может ли кто-нибудь сделать мне одолжение?

std::cout << "unique ownership semantics demo\n";
  {
      auto p = std::make_unique<D>(); 
      std::cout << p.get() << std::endl;  //I think p is an object, not an pointer.
      auto q = pass_through(std::move(p)); 
      assert(!p);  //Why it is legial?
      q->bar();   
  } 

Ответы [ 3 ]

4 голосов
/ 26 мая 2020

Когда !p скомпилирован, компилятор неявно вызывает operator bool, который есть unique_ptr<T>, а затем отменяет это.

См. здесь для более подробной информации.

3 голосов
/ 26 мая 2020

!p является допустимым, поскольку существует явно определенная функция для преобразования unique_ptr в bool.

См. https://en.cppreference.com/w/cpp/memory/unique_ptr/operator_bool

explicit operator bool() const noexcept;

!p переводится как !(p.operator bool()).

1 голос
/ 26 мая 2020

Чтобы ответить на ваш другой вопрос:

std::cout << p.get() << std::endl; работает, потому что

  • get() возвращает указатель, удерживаемый unique_ptr
  • operator<< имеет перегрузку, которая принимает указатель void* в качестве входных данных
  • любой указатель неявно преобразуется в void*.

p действительно является объектом, а не указателем. Но get() возвращает указатель.

...