我正在实现与std::vector
非常相似的东西,但在堆栈上使用数组而不是内存分配。
d-tor调用使用SFINAE的函数。
value_type
是POD,则该函数具有空体。value_type
是普通类std::string
,则该函数会有一个正文并正确销毁所有数据。现在,我希望能够将这个新的std::vector
用作constexpr
。然而,即使c-tor被声明为constexpr
,代码也不会编译,因为该类具有非平凡的d-tor。
以下是代码的一小部分:
template<typename T, std::size_t SIZE>
class SmallVector{
constexpr SmallVector() = default;
~SmallVector(){
destructAll_<value_type>();
}
// ...
template<typename X>
typename std::enable_if<std::is_trivially_destructible<X>::value == true>::type
destructAll_() noexcept{
}
};
如果constexpr
是POD并且保留非POD数据类型的功能,我可以做些什么来使类成为value_type
。
(当然不是在同一时间)
答案 0 :(得分:6)
不幸的是,无法使用SFINAE启用/禁用析构函数,也无法使用未来的概念。那是因为destructos:
你可以做的是专门化整个类,或者更好的是,创建一个只包含构造/破坏和基本访问的基类,并将其专门化。
template <class T, class Enable = void>
struct X {
~X() {}
};
template <class T>
struct X<T, std::enable_if_t<std::is_pod<T>::value>> {
};
static_assert(std::is_trivially_destructible<X<int>>::value);
static_assert(!std::is_trivially_destructible<X<std::vector<int>>>::value);
答案 1 :(得分:-3)
析构函数中if constexpr
的例子。 (需要 C++17)
template<typename Tp, typename TLock>
struct LockedPtr {
private:
Tp *m_ptr;
TLock *m_lk;
void prelock(std::mutex *mtx) { mtx->lock(); }
void prelock(std::atomic_flag *atom) { while(atom->test_and_set(std::memory_order_acquire)); }
public:
LockedPtr(Tp *ptr, TLock *mtx)
: m_ptr(ptr), m_lk(mtx) {
prelock(mtx);
}
~LockedPtr() {
if constexpr (std::is_same_v<TLock, std::mutex>)
((std::mutex *)m_lk)->unlock();
if constexpr (std::is_same_v<TLock, std::atomic_flag>)
((std::atomic_flag *)m_lk)->clear(std::memory_order_release);
}
};
这些代码是 RAII 锁定智能指针的一部分,通过 std::mutex
来采用普通的 std::atomic_flag
和自旋锁。
if constexpr
匹配类型并使某些内容无法转换为析构函数中的指针。