我正在阅读的 STL 代码可能是旧的......但问题更多与 C++ 模板语法有关。
问题围绕着这个STL模板函数:
template<class T> std::destroy(T *p) {
p->~T();
}
我似乎找不到 std::destroy(T *) 函数的特化。所以在我看来,模板函数将为“int”类型实例化相同的类型,并调用“int”的析构函数。为了说明我的观点,我创建了这个模拟 std::destroy 的示例代码。我把它叫做 my_destroy 在这个例子中。
#include <iostream>
#include <stdio.h>
using namespace std;
template <class T>
void my_destroy(T * pointer) {
pointer->~T();
}
int main()
{
int *a;
//a->~int(); // !!! This won't compile.
my_destroy<int>(a); // !!! This compiles and runs.
}
}
令我惊讶的是,这一行无法编译:
a->~int();
但这行编译:
my_destroy<int>(a);
我的困惑是,我认为 my_destroy<int>(a)
将被实例化为 a->~int();
对于一个更大的问题,当 <int>
的 STL 容器时删除一个元素,std::destroy()
如何工作吗?
最佳答案
请注意,虽然 a->~int();
不能编译,但它可以:
typedef int INT;
int* a;
a->~INT();
来自标准:
5.2.4p1 在点之后使用 pseudo-destructor-name
。或箭头 -> 运算符表示由 type-name
或 decltype-specifier
表示的非类类型的析构函数。结果只能用作函数调用运算符 () 的操作数,并且这种调用的结果类型为 void。唯一的影响是在点或箭头之前计算后缀表达式。
从 5.2p1:
pseudo-destructor-name:
nested-name-specifier_opt type-name :: ~ type-name
nested-name-specifier template simple-template-id :: ~ type-name
nested-name-specifier_opt~ type-name
~ decltype-specifier
最后,7.1.6.2p1:
type-name:
class-name
enum-name
typedef-name
simple-template-id
所以,奇怪的是,int
在语法上不是 type-name
(它是一个 simple-type-specifier
),所以你可以' t 调用 ~int()
,但 INT
是,所以你可以。
关于C++ std::destroy(T * 指针),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17755729/