问题
If I have a virtual function that carries an attribute
[[nodiscard]]
virtual bool some_function() = 0;
Does that attribute get implicitly applied to overrides of that function?
bool some_function() override;
Or do I need the attribute again?
[[nodiscard]]
bool some_function() override;
回答1:
I can't see any evidence in the C++17 wording that attributes are inherited by overriding functions.
The most relevant section I can find is the rules for overriding:
[class.virtual]/2:
If a virtual member functionvf
is declared in a classBase
and in a classDerived
, derived directly or indirectly fromBase
, a member functionvf
with the same name, parameter-type-list (11.3.5), cv-qualification, and ref-qualifier (or absence of same) asBase::vf
is declared, thenDerived::vf
is also virtual (whether or not it is so declared) and it overridesBase::vf
. [..]
While this passage attacks the problem from a slightly different angle, I think it's enough to show that only virtualness is "inherited" (and that attributes don't come into play at all when deciding whether one function overrides another). That being said, I think this is slightly underspecified and could do with a clarifying note at the very least.
Of course, this quickly gets complicated. Given the below example:
struct B {
[[nodiscard]] virtual bool foo() { return true; }
};
struct D : B {
bool foo() override { return false; }
};
int main() {
D().foo();
}
Clang will not issue a warning. However, access the function through a base pointer and it will.
struct B {
[[nodiscard]] virtual bool foo() { return true; }
};
struct D : B {
bool foo() override { return false; }
};
int main() {
D d;
((B*)&d)->foo();
}
What that means for your question, I'm not sure.
Again, I'd like to see a bit more guidance from the standard on this topic.
回答2:
I sent an email to the C++ committee, specifically the Core working group, and provided the above example.
CoryKramer
It is currently unclear from the standard if attributes applied to virtual functions are inherited.
Response:
They are not. For them to be inherited, the Standard would have to explicitly say so, and it does not.
CoryKramer:
[After providing above code example] In the above example, I would expect both lines calling
foo()
to emit a compiler warning. I would hope that the attribute applies to all derived functions for consistency.
Response:
That's one perspective. Another is that, especially with covariant return types where the derived function returns a different type from that of the base function, it might very well be useful to make the base return type
[[nodiscard]]
but not the derived return type. There's currently no way to mark the derived function as not-[[nodiscard]]
.More generally, it seems reasonable to get a different set of attributes when calling a derived function from those you get when calling the base function. If you know you have a derived class object, you have more specific information and behavior than if all you know is that it's a base class object, and attributes on member functions are part of that extra knowledge.
Reponses by Mike Miller of the C++ Core Working Group (3/30/2018).
来源:https://stackoverflow.com/questions/49576298/are-function-attributes-inherited