为什么析构函数不能有引用限定符?

9

除了“因为标准规定如此”的原因外,以下代码不允许的原因是什么?

struct Foo
{
    ~Foo() && {}
    ~Foo() & {}
};

我知道这是非法的,但我想知道为什么。

我在思考一个老问题-避免未命名实例,例如在使用守卫对象时:

void do_something()
{
    std::lock_guard{my_mutex};
    // some synchronized operation
}

这是合法的代码,但显然容易出错,因为锁守卫在构造完成后会立即被销毁,因为它是一个临时(无名)对象。

我计划做这样的事情

struct Foo
{
    ~Foo() && = delete;
    ~Foo() & = default;
};

如果以临时方式构建类型,则会收到编译器错误提示。


6
这里的参考资格限定词应该有什么目的? - t.niese
1
你有什么需求? - Build Succeeded
2
我认为,因为析构函数销毁对象,所以它不应该有任何限定符。被引用的对象永远不会被销毁。如果一个类使用这些限定符,你会怎么做? - Gerhard Stein
1
@Dr.-Ing.GerhardStein,不确定您所说的“引用对象永远不会被销毁”是什么意思。这正是悬空引用的来源。 - Timo
1
如果没有相同的构造函数,我真的看不出有这个的意义。 - geza
显示剩余8条评论
1个回答

4

首先,每个类只能有一个析构函数。允许在析构函数上使用 ref-qualifiers 将使得重载析构函数成为可能。

另一个可能的原因是为了与 const volatile 限定符保持一致:

析构函数不应该被声明为constvolatileconst volatile(9.3.2)。 const volatile 语义(7.1.5.1)不适用于正在销毁的对象

我猜为了保持一致,在销毁对象时不区分 rvalues lvalues


1
有趣的是,如果我们允许引用限定符,那么这种行为的改变会影响现有的代码吗? - Timo
这只是一个“因为标准规定如此”的答案,没有真正回答为什么。当然,如果我们有&&&析构函数,那就意味着重载析构函数。这就是问题所在。 - geza
1
@Timo 我认为它是向后兼容的,因为现有的代码没有使用它。 - JFMR

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接