作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
<分区>
我创建了一个类模板,其析构函数在编译器不激活的情况下无法实例化 static_assert
:
文件:M.hpp
template <typename T>
struct M
{
M(){}
~M()
{
static_assert(sizeof(T) == 0, "no type can pass this");
}
};
接下来我以两种不同的方式使用这个类:在堆上分配它和在堆栈上分配它:
文件 main.cpp
#include "M.hpp"
int main()
{
M<int> *pmi = new M<int>(); // does compile
M<int> mi; // doen't compile
}
在堆上分配它 M<int> *pmi = new M<int>();
作品。之所以如此,是因为我们只使用构造函数而不需要析构函数。类模板隐式实例化规则say :
... unless the member is used in the program, it is not instantiated ...
在栈上分配 M<int> mi;
不起作用,因为编译器肯定需要实例化析构函数。
到目前为止一切顺利,规则清晰。
我写了另一个使用 M
的类作为成员(member):
文件 X.cpp
#include "M.hpp"
struct X
{
X() = default;
~X() = delete;
private:
M<int> m_;
};
我故意删除了析构函数,因为我不希望它以任何方式干扰我的实验。构造函数是默认的,据我所知,它应该只生成 M<int>
的构造函数,它的唯一成员,并调用它。令我惊讶的是,情况并非如此。 X()
还尝试生成 M<int>
的析构函数:
文件 main.cpp
#include "X.hpp"
int main()
{
X* px = new X();
}
这是我从编译器得到的:
$ g++ -std=c++17 main.cpp
In file included from X.hpp:1,
from main.cpp:1:
M.hpp: In instantiation of ‘M<T>::~M() [with T = int]’:
X.hpp:5:3: required from here
M.hpp:7:29: error: static assertion failed: no type can pass this
static_assert(sizeof(T) == 0, "no type can pass this");
问题是:为什么在默认构造函数的实例化过程中,如果不需要,编译器会尝试为成员类模板实例化析构函数?如果确实需要它,你能指出它所在的文档吗?
我是一名优秀的程序员,十分优秀!