Date: Mon, 9 Oct 2023 17:36:55 +0200
Hi
did anybody use so far destroying delete in CRTP base class templates
for correctly deleting via base pointer in C++20?
See my example:
https://godbolt.org/z/PWPxYdj5q
==========
#include <iostream>
#include <memory>
#include <type_traits>
template<typename TAG, typename destroyer_t>
constexpr
TAG *destroyer_cast(destroyer_t*ptr){
static_assert(std::is_base_of_v<destroyer_t,TAG>);
return static_cast<TAG*>(ptr);
}
template<typename derived>
struct base {
~base() { std::cout << "base dtor \n";}
// simulate mix-in function:
friend void print(derived const& d){
std::cout << typeid(decltype(d)).name()<<'\n';
}
// only available in C++20
#ifdef __cpp_impl_destroying_delete
void operator delete( base* ptr, std::destroying_delete_t )
{
// cannot check if TAG is subtype here directly,
// because derived might be incomplete
// therefore indirect the static_cast
destroyer_cast<derived>(ptr)->~derived();
::operator delete((void*)ptr);
}
#endif
};
struct d: base<d> {
using base = base<d>;
~d() { std::cout << "derived dtor\n";}
};
int main(){
auto p = std::make_unique<d>();
print(*p);
std::unique_ptr<d::base> pb {std::move(p)};
}
========
did anybody use so far destroying delete in CRTP base class templates
for correctly deleting via base pointer in C++20?
See my example:
https://godbolt.org/z/PWPxYdj5q
==========
#include <iostream>
#include <memory>
#include <type_traits>
template<typename TAG, typename destroyer_t>
constexpr
TAG *destroyer_cast(destroyer_t*ptr){
static_assert(std::is_base_of_v<destroyer_t,TAG>);
return static_cast<TAG*>(ptr);
}
template<typename derived>
struct base {
~base() { std::cout << "base dtor \n";}
// simulate mix-in function:
friend void print(derived const& d){
std::cout << typeid(decltype(d)).name()<<'\n';
}
// only available in C++20
#ifdef __cpp_impl_destroying_delete
void operator delete( base* ptr, std::destroying_delete_t )
{
// cannot check if TAG is subtype here directly,
// because derived might be incomplete
// therefore indirect the static_cast
destroyer_cast<derived>(ptr)->~derived();
::operator delete((void*)ptr);
}
#endif
};
struct d: base<d> {
using base = base<d>;
~d() { std::cout << "derived dtor\n";}
};
int main(){
auto p = std::make_unique<d>();
print(*p);
std::unique_ptr<d::base> pb {std::move(p)};
}
========
-- Peter Sommerlad Better Software: Consulting, Training, Reviews Modern, Safe & Agile C++ peter.cpp_at_[hidden] +41 79 432 23 32
Received on 2023-10-09 15:36:59