为什么析构函数不能是模板
Why destructor cannot be template?
我不想在类联合中使用SFINAE禁用用户声明的析构函数,就像在类中使用构造函数一样:
#include <type_traits>
#include <cstdlib>
template< typename A, typename B >
struct U
{
constexpr U() = default;
constexpr U(A _a) : a(_a), s{false} {}
constexpr U(B _b) : b(_b), s{true} {}
union
{
A a;
B b;
};
bool s;
template< typename = std::enable_if_t< !(std::is_trivially_destructible< A >{} && std::is_trivially_destructible< B >{}) >, // disable if A and B is trivially destructible
bool is_noexcept = (noexcept(std::declval< A >().~A()) && noexcept(std::declval< B >().~B())) > // disable if A or B is not destructible
~U() noexcept(is_noexcept)
{
if (s) {
b.~B();
} else {
a.~A();
}
}
};
int main()
{
struct A {};
struct B {};
U< A, B > u;
static_assert(std::is_literal_type< A >{});
static_assert(std::is_literal_type< B >{}); // =>
static_assert(std::is_literal_type< U< A, B > >{});
return EXIT_SUCCESS;
}
但出现错误:
main.cpp:24:5: error: destructor cannot be declared as a template
~U() noexcept(is_noexcept)
^
1 error generated.
Failure!
C++中存在这种限制的理论原因吗?还是仅仅是"遗产"?
任何类U
都可以有一个且只有一个析构函数,该析构函数在名为~U()
的类中声明,不接受任何参数。
模板函数指定函数族;家庭;描述一个包含一个或多个成员的集合,对成员数没有上限。
这两个概念是相互排斥的。一个类不能同时只有一个析构函数和一系列析构函数。
作为解决方案,您可以添加层和专业化,比如:
template <typename A, typename B,
bool trivially_destructible = std::is_trivially_destructible<A>{}
&& std::is_trivially_destructible<B>{},
bool is_no_except = noexcept(std::declval<A>().~A())
&& noexcept(std::declval<B>().~B())>
struct UdestructorImpl;
template <typename A, typename B, bool is_no_except>
struct UdestructorImpl<A, B, true, is_no_except>
{
~UdestructorImpl() noexcept(is_no_except) = default;
}
template <typename A, typename B, bool is_no_except>
struct UdestructorImpl<A, B, false, is_no_except>
{
~UdestructorImpl() noexcept(is_no_except) = delete;
}
template< typename A, typename B > struct U : UdestructorImpl<A, B>
{
// Implementation
};
相关文章:
- 为什么这里不调用析构函数
- 为什么在运算符删除中不调用析构函数?
- 如果引用应该保留,不删除析构函数中的指针会导致内存泄漏吗?
- 单例:为什么不需要删除并且看不到析构函数调试消息
- 为什么移动运算符不只是析构函数+移动构造函数
- 我不明白析构函数有什么问题?
- 从 std::streambif 继承时不兼容析构函数编译器警告
- 可观察行为和未定义行为 -- 如果我不调用析构函数会发生什么?
- 为什么C++ std::list::clear() 不调用析构函数
- c++中的Guard,在main中未处理异常时不调用析构函数
- 删除类数组而不调用析构函数
- 移动构造函数不调用析构函数
- 删除 void 指针时不调用析构函数
- 为什么在删除析构函数时调用析构函数,如果未删除则不调用析构函数?
- 在构造函数中引发异常时不调用析构函数
- 为什么在数组创建期间抛出未捕获的异常时不调用析构函数C++?
- C++:为什么它不调用析构函数?
- 在不调用析构函数的情况下结束STL容器的生存期
- 为什么在 main 中未捕获异常时不调用析构函数?
- c# /CLI:如果在其中使用Dispose(),则不调用析构函数