C++ std :: destroy(T*指针)

ROT*_*OGG 22 c++ stl

我正在阅读的STL代码可能很旧......但问题与C++模板语法有关.

问题围绕着这个stl模板函数:

template<class T> std::destroy(T *p) {
    p->~T();
}
Run Code Online (Sandbox Code Playgroud)

我似乎无法找到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.
}
Run Code Online (Sandbox Code Playgroud)

}

令我惊讶的是,这行不编译:

a->~int();
Run Code Online (Sandbox Code Playgroud)

但这一行编译:

my_destroy<int>(a);
Run Code Online (Sandbox Code Playgroud)

我的困惑是,我认为这my_destroy<int>(a)将被实例化为相当于a->~int();

对于更大的上下文中的问题,当STL容器<int>擦除元素时,如何std::destroy()工作?

Igo*_*nik 33

请注意,虽然a->~int();不编译,但这样做:

typedef int INT;
int* a;
a->~INT();
Run Code Online (Sandbox Code Playgroud)

从标准:

5.2.4p1使用a pseudo-destructor-name后点.或箭头 - >运算符表示由type-name或表示的非类类型的析构函数decltype-specifier.结果只能用作函数调用operator()的操作数,并且这种调用的结果类型为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
Run Code Online (Sandbox Code Playgroud)

最后,7.1.6.2p1:

type-name:
  class-name
  enum-name
  typedef-name
  simple-template-id
Run Code Online (Sandbox Code Playgroud)

所以,奇怪的int是,语法不是type-name(它是a simple-type-specifier)所以你不能打电话~int(),但是INT你可以这样做.


seh*_*ehe 3

该语言允许这些东西实现通用编程。但是,您的“直接”调用不是通用代码,因此它会失败。

另一个这样的案例是

template <typename T> void foo()
{
    T instance = T(); // default constructor
}

foo<int>(); // will work
Run Code Online (Sandbox Code Playgroud)

所以,是的:

template <typename T> void foo()
{
    T* instance = new T(); // default constructor
    delete instance;      
}
Run Code Online (Sandbox Code Playgroud)

也适用于内置基本类型,因为T是模板范围内的类型名称。