使用 noexcept 运算符依赖

Use noexcept operator depenendet

我想知道是否可以使用 C++11 的 noexcept operator 来定义 e 的 noextcept 说明符。 G。调用另一个 class 方法的析构函数(例如 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_;
 // ...
};

问题: 根据委托类型的使用方法(例如 std::allocator)定义 noexcept 的最佳解决方案是什么? 当存在不同的重载时,必须做些什么 - 如果可能的话 - 使用委托类型的方法(例如,当不只提供一个时,我将如何使用特定的解除分配实现)?

指出了一个解决方案:

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

只要该方法只存在一个重载,此解决方案就有效。如果有人可以提供更好的解决方案(更好读,可重用......)或也适用于具有重载的方法的解决方案,请提供。

Edit/Update: 一位同事和下面 Yakk 的回答提供了一个更好的解决方案,该解决方案还涵盖了不同的重载:

~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_);
    }
}

中,这很简单:

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

Live example.

但是在 做起来很痛苦 "properly":

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

Live example.

所以,升级到

你也可以黑手做:

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

但你必须小心,因为传递 nullptr_t 可能会给你错误的答案(因此上面从 nullptr 转换为 uint8_t*,并避免使用 0 作为文字)。