如果我的虚函数带有attribute
[[nodiscard]]
virtual bool some_function() = 0;
该属性是否隐式应用于该函数的覆盖?
bool some_function() override;
或者我是否还需要该属性?
[[nodiscard]]
bool some_function() override;
答案 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)。