我发现在 C++17 中,std::allocator::destroy
被废弃了:
http://zh.cppreference.com/w/...
而替代方案是显示调用析构函数。就此我产生了一个疑问,为了描述清楚,先构造一个类:
template<typename T> class Object {
T* data_;
public:
Object() { data_ = (T*) malloc(sizeof(T)); }
void Construct() { new (data_) T(); }
void Destory() { data_->~T(); }
T& operator->() { return *data_; }
~Object() { free(data_); }
};
我认为 Object<int>::Destory()
会导致 data_->~int()
,而后者自然是不能通过编译的。
但测试发现,Object<int> o
的构造不会产生编译错误(g++ (Ubuntu 4.9.3-13ubuntu2) 4.9.3)。那么:
- 这种行为是 C++ 标准的,还是 g++ 特有的?
- 应该怎样阐述
data_->~T()
的行为?
感谢 @felix 指教,为了清晰起见,我自答一下:
这个行为是 C++ 标准的,还是 g++ 特有的?
这种行为是 C++ 标准的。参考:
http://zh.cppreference.com/w/...
之中【内建的成员访问运算符】,第四种用法:
expr 是一个标量类型,pseudo-destructor 为一个 ~ 之后跟着代表与 expr 相同类型的类型名,所构成的函数调用表达式被称为伪析构函数调用。它不接受任何参数,返回 void,且除了对开头的 expr 求值之外不实施任何操作。允许进行伪析构函数调用,使得编写代码而无需了解某个给定类型是否存在析构函数成为可能。
上面叙述中的类型名(type name)对当前语法来说,可以指 typedef 或者 using(type alias)声明的名字,而不指类型本身。举例说明:
data_->~T()
的行为?当 T 是标量类型(可有 cv 限定的算术、指针、指向成员指针、枚举或 std::nullptr_t 类型)时,它表示伪析构函数调用,即除了对
data_
取值不做任何事。当 T 不是标量类型时,它显式调用了
data_
的析构函数。这种行为让
data_->~T()
的调用变得很理想。