Использовать оператор noexcept для зависимости - PullRequest
0 голосов
/ 22 октября 2018

Интересно, можно ли использовать оператор C ++ 11 noexcept для определения спецификатора noextcept, например, деструктора, который вызывает метод другого класса (например, std :: allocator :: deallocate):

template <class DelegateAllocator = std::allocator<uint8_t>>
class MyAllocator final {
 public:
  using allocator_type = DelegateAllocator;

  // ...

  ~MyAllocator() noexcept(noexcept(/* what to use */))) {
    if (memory_ != nullptr) {
      allocator_.deallocate(memory_, length_);
    }
  }

private: 
 allocator_type allocator_;   
 uint8_t* memory_;
 // ...
};

Вопросы: Как лучше всего определить noexcept в зависимости от используемых методов делегированного типа (например, std :: allocator)?Что нужно сделать - когда это возможно - чтобы использовать методы делегированного типа, когда существуют разные перегрузки (например, как бы я использовал конкретную реализацию освобождения, когда предоставляется не только одна)?

Ответы [ 2 ]

0 голосов
/ 22 октября 2018

В это так же просто, как:

~MyAllocator() noexcept(noexcept(std::declval<allocator_type&>().deallocate( memory_, allocator_ ))) {
  if (memory_ != nullptr) {
    allocator_.deallocate(memory_, length_);
  }
}

Живой пример .

Но в больно делать «правильно»:

 ~MyAllocator() noexcept(noexcept(std::declval<allocator_type&>().deallocate( std::declval<uint8_t*&>(), std::declval<std::size_t&>() ))) {
    if (memory_ != nullptr) {
      allocator_.deallocate(memory_, length_);
    }
  }

Живой пример .

Итак, обновитесь до .

Вы также можете сделать это с радостью:

 ~MyAllocator() noexcept(noexcept(std::declval<allocator_type&>().deallocate( (uint8_t*)nullptr,1 ))) {

, но вы должны быть осторожны, потому что прохождение nullptr_t может дать вам неправильный ответ (отсюда приведенный выше актерский составот nullptr до uint8_t* и избегая использования 0 в качестве литерала).

0 голосов
/ 22 октября 2018

Этот ответ о переполнении стека указал мне на одно решение:

~StackAllocator() noexcept(noexcept(std::declval<allocator_type>().*&allocator_type::deallocate)) {
    if (memory_ != nullptr) {
      allocator_.deallocate(memory_, length_);
    }
}

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

Редактирование / обновление: Коллега и ответ от Якка ниже представили лучшее решение, которое также охватывает различные перегрузки:

~StackAllocator() noexcept(noexcept(std::declval<allocator_type>().deallocate(std::declval<std::uint8_t*>(), std::declval<std::size_t>()))) 
{
    if (memory_ != nullptr) {
        allocator_.deallocate(memory_, length_);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...