函数属性是否继承?

时间:2018-03-30 14:31:13

标签: c++ attributes c++17

如果我的虚函数带有attribute

[[nodiscard]]
virtual bool some_function() = 0;

该属性是否隐式应用于该函数的覆盖?

bool some_function() override;

或者我是否还需要该属性?

[[nodiscard]]
bool some_function() override;

2 个答案:

答案 0 :(得分:4)

我无法在C ++ 17中看到任何证据表明属性是由覆盖函数继承的。

我能找到的最相关的部分是覆盖规则:

  

[class.virtual]/2:如果虚拟成员函数vf在类Base和类Derived中声明,直接或间接来自Base,成员函数vf 同名,参数类型列表(11.3.5), cv-qualification ref-声明了{{1>}的限定符 (或不存在),然后Base::vf也是虚拟的(无论是否如此声明)并且覆盖 Derived::vf [..]

虽然这段话从一个稍微不同的角度来解决这个问题,但我认为这足以表明只有虚拟才能继承并且#34; (当决定一个函数是否覆盖另一个函数时,这些属性根本不起作用)。话虽如此,我认为这有点不明确,至少可以做一个澄清的说明。

当然,这很快变得复杂。鉴于以下示例:

Base::vf

Clang不会发出警告。但是,通过基指针访问该函数,它将会。

struct B {
    [[nodiscard]] virtual bool foo() { return true; }
};

struct D : B {
    bool foo() override { return false; }
};

int main() {
    D().foo();
}

这对你的问题意味着什么,我不确定。

同样,我希望从这个主题的标准中获得更多指导。

答案 1 :(得分:3)

我发送了一封电子邮件给C ++委员会,特别是Core工作组,并提供了上面的例子。

CoryKramer

  

目前尚不清楚标准中是否继承了应用于虚函数的属性。

回应:

  

他们不是。为了让他们继承,标准必须明确说明,而不是。

CoryKramer:

  

[提供上面的代码示例]在上面的例子中,我希望两行调用foo()发出编译器警告。我希望该属性适用于所有派生函数的一致性。

回应:

  

这是一个观点。另一个是,特别是对于协变返回类型,其中派生函数返回与基函数不同的类型,使得基本返回类型[[nodiscard]]而不是派生返回类型可能非常有用。目前无法将派生函数标记为 - [[nodiscard]]

     

更一般地说,从调用基函数时获得的函数调用派生函数时,获取一组不同的属性似乎是合理的。如果你知道你有一个派生类对象,那么你拥有的特定信息和行为比你所知道的它是一个基类对象,并且成员函数的属性是这些额外知识的一部分。

C ++核心工作组Mike Miller的回复(3/30/2018)。