即使在内置素上实例化,也可以向模板参数类型的驱动器进行明确调用



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();

bool上进行T型T型时编译并运行正常,但是使用实际的bool

进行相同的操作
((bool*)buffer)->~bool();

是语法错误。

我发现了这种行为,因为我正在进行模板元编程,并发现它非常有用,因此我猜这是标准的,并专门为处理上面的案例而添加了专门处理案例。有人确定是否确实是这种情况,当这种行为是标准化时是否是这种情况?

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

这确实是有效的c (据我所知,自C 98起),并且被称为a pseudo-Destructor call 。N4431§5.2.4[expr.pseudo]:

1使用a pseudo-destructor-name dot .或箭头 -> 运算符代表非类型的破坏者 type-name decltype-pexifier 。结果仅应用作函数调用操作员()的操作数,并将其结果 这样的呼叫具有void类型。唯一的效果是评估 postfix-expression 在点或箭头之前。

2点运算符的左侧应为标量类型。这 箭头操作员的左侧应为标量的指针 类型。此标量类型是对象类型。CV UNQUALIFIFIFIFIFIFIFIFIFIFIST 对象类型和由 伪破坏者名称应是相同的类型。此外,形式的A pseudo-Destructor-name

中的两个 type-names
nested-name-specifier_opt type-name :: ~ type-name

应指定相同的标量类型。

a pseudo-destructor-name 是(§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()版本编译。

最新更新