gpt4 book ai didi

c++ - 显式调用模板参数类型的析构函数,即使在内置函数上实例化时也是如此

转载 作者:IT老高 更新时间:2023-10-28 23:18:22 24 4
gpt4 key购买 nike

C++ 程序(起初对我来说有点出乎意料)编译并运行良好,除了 main() 末尾注释的行,如果它是编译时错误未注释。

#include <typeinfo>
#include <iostream>

struct Foo {
int x;
};

template <typename T>
void create(char *buffer)
{
std::cout << "creating " << typeid(T).name() << std::endl;
new (buffer) T();
}

template <typename T>
void destroy(char *buffer)
{
std::cout << "destroying " << typeid(T).name() << std::endl;
((T*)buffer)->~T();
}

int main(int argc, char **argv)
{
char buffer[sizeof(Foo) > sizeof(bool) ? sizeof(Foo) : sizeof(bool)];

// create/destroy Foo via template function calls
create<Foo>(buffer);
destroy<Foo>(buffer);
// now do the above explicitly...
new (buffer) Foo();
((Foo*)buffer)->~Foo();

// create/destroy bool via template function calls
create<bool>(buffer);
destroy<bool>(buffer);
// now do the above explicitly...
new (buffer) bool();
// ((bool*)buffer)->~bool(); // oops, doesn't work

return 0;
}

我从中收集到 C++(或至少 g++ 对 C++ 的想法)允许模板参数类型的“显式析构函数调用”,即使手动执行类型替换会导致语法错误(因为 bool 实际上并没有要调用的析构函数)。

更明确地说,这行:

((T*)buffer)->~T();

当 T 在 bool 上实例化时编译并运行良好,但对实际 bool 做同样的事情:

((bool*)buffer)->~bool();

是语法错误。

我在进行模板元编程时发现了这种行为,并发现它非常有帮助,所以我猜它是标准的,并且是专门为处理我上面提到的情况而添加的。有谁知道这是否真的是这样,如果是,这种行为何时被标准化?

此外,任何人都可以指出标准中允许这样做的确切措辞以及它允许​​的情况范围吗? (我不擅长阅读标准语,所以我自己很难弄清楚这一点。)

最佳答案

这确实是有效的 C++(据我所知,自 C++98 以来一直存在),并且被称为 伪析构函数调用。 N4431 §5.2.4 [expr.pseudo]:

1 The use of a pseudo-destructor-name after a dot . or arrow -> operator represents the destructor for the non-class type denoted by type-name or decltype-specifier. The result shall only be used as the operand for the function call operator (), and the result of such a call has type void. The only effect is the evaluation of the postfix-expression before the dot or arrow.

2 The left-hand side of the dot operator shall be of scalar type. The left-hand side of the arrow operator shall be of pointer to scalar type. This scalar type is the object type. The cv-unqualified versions of the object type and of the type designated by the pseudo-destructor-name shall be the same type. Furthermore, the two type-names in a pseudo-destructor-name of the form

nested-name-specifier_opt type-name :: ~ type-name

shall designate the same scalar type.

伪析构函数名称是(§5.2 [expr.post])之一:

nested-name-specifier_opt type-name :: ~ type-name
nested-name-specifier template simple-template-id :: ~ type-name
~ type-name
~ decltype-specifier

type-name 是 (§7.1.6.2 [dcl.type.simple]) 之一

class-name
enum-name
typedef-name
simple-template-id

bool 不是 type-name,因此 ~bool() 版本是语法错误。在模板内部,模板类型参数是一个typedef-name(§14.1 [temp.param]/p3),它是一个type-name,所以~T() 版本编译。

关于c++ - 显式调用模板参数类型的析构函数,即使在内置函数上实例化时也是如此,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30206864/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com