箭头运算符 -> 和范围解析运算符 :: 的组合是什么意思?

问题描述 投票:0回答:1

cppreference.com – “限定名称查找”,我发现了这个奇怪的代码示例:

struct C { typedef int I; };

typedef int I1, I2;

extern int *p, *q;

// Slight modification to prevent linker error
//struct A { ~A(); };
struct A { ~A() {}; };

typedef A AB;

int main()
{
    p->C::I::~I(); // The name I after ~ is looked up in the same scope as I before ::
                   // (that is, within the scope of C, so it finds C::I)

    q->I1::~I2();  // The name I2 is looked up in the same scope as I1
                   // (that is, from the current scope, so it finds ::I2)

    AB x;
    x.AB::~AB();   // The name AB after ~ is looked up in the same scope as AB before ::
                   // (that is, from the current scope, so it finds ::AB)
}

令我惊讶的是,编译没有任何错误。但到底发生了什么

p->C::I::~I();
q->I1::~I2();

?这不仅看起来像是访问

int
变量的成员并以某种方式引用
int
析构函数,而且
p
q
也是没有任何定义的
extern
变量。

为什么允许这种语法,它实际上做了什么?

c++ syntax member-access scope-resolution-operator
1个回答
0
投票

这些是伪析构函数调用。不使用类型别名的限定查找的直接表示法是

p->~int();
q->~int();

如果

x.~T()
是标量类型而不是类类型,则符号
p->~T()
T
始终是伪析构函数调用。在这种情况下,
x
必须具有类型
T
p
类型
int*

伪析构函数调用结束对象的生命周期

x
/
*p
,就像普通的析构函数调用一样,但不执行任何其他操作。它的存在只是为了让人们可以编写适用于类和非类类型的通用代码,而无需在使用析构函数调用时编写不同的情况。

但是 p 和 q 也是没有任何定义的外部变量。

伪析构函数调用 odr-use

p
q
,因此程序中必须存在它们的定义。但是,它可能位于不同的翻译单元中。即使它不存在,这样的 odr 违规也会使程序 IFNDR(格式错误,无需诊断),因此编译器不会have 抱怨它。毕竟,这些行实际上不会导致发出任何机器代码,因此没有理由打扰链接器寻找
p
q
的定义。

© www.soinside.com 2019 - 2024. All rights reserved.