使用 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_);
}
}
在 c++14 中,这很简单:
~MyAllocator() noexcept(noexcept(std::declval<allocator_type&>().deallocate( memory_, allocator_ ))) {
if (memory_ != nullptr) {
allocator_.deallocate(memory_, length_);
}
}
但是在 c++11 做起来很痛苦 "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_);
}
}
所以,升级到 c++14。
你也可以黑手做:
~MyAllocator() noexcept(noexcept(std::declval<allocator_type&>().deallocate( (uint8_t*)nullptr,1 ))) {
但你必须小心,因为传递 nullptr_t
可能会给你错误的答案(因此上面从 nullptr
转换为 uint8_t*
,并避免使用 0
作为文字)。
我想知道是否可以使用 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_);
}
}
在 c++14 中,这很简单:
~MyAllocator() noexcept(noexcept(std::declval<allocator_type&>().deallocate( memory_, allocator_ ))) {
if (memory_ != nullptr) {
allocator_.deallocate(memory_, length_);
}
}
但是在 c++11 做起来很痛苦 "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_);
}
}
所以,升级到 c++14。
你也可以黑手做:
~MyAllocator() noexcept(noexcept(std::declval<allocator_type&>().deallocate( (uint8_t*)nullptr,1 ))) {
但你必须小心,因为传递 nullptr_t
可能会给你错误的答案(因此上面从 nullptr
转换为 uint8_t*
,并避免使用 0
作为文字)。