No whitespace between a cast and a namespace operator?
Could anyone please explain 开发者_Python百科the following line of code, found on http://docs.openttd.org/ai__cargo_8cpp_source.html
return (AICargo::TownEffect)::CargoSpec::Get(cargo_type)->town_effect;
If this line was:
return (AICargo::TownEffect) ::CargoSpec::Get(cargo_type)->town_effect;
(note the space between TownEffect)
and the ::
) then I would understand it fine. However there is no whitespace in that document*, which would mean (AICargo::TownEffect)
is the left operand of the :: operator.
How does this code work/compile? Or are the two things equivilent due to some obscure C++ rule?
*It's the same in the cpp file as well.
Other than separating tokens, white space is generally not significant in C++ grammar.
Parentheses are significant, and they can't appear in a qualified-id so there is no equivalence between:
(AICargo::TownEffect)::CargoSpec::Get
and
AICargo::TownEffect::CargoSpec::Get
In the first there are two qualified-ids, one in parentheses naming a type and the other naming a function. The only valid interpretation of a parenthesized type in this context is as a cast-expression. Whether there is a space after the closing parenthesis makes no difference.
It's a simple problem of parsing: the whitespace is not necessary here because we know that the C-style cast ends with the parenthesis.
It's no more unreadable that:
if(cargo_type){return cargo_type->town_effect;}
It probably stems from the fact that (
and )
cannot be part of an identifier.
Charles is right above when he says that there can be no parentheses in a qualified-id.
I want to add that in C++ you shouldn't be using the old C-style casts as a matter of style. They're typically stronger than you want and cast away const
ness, which is very often not what you want. Additionally, they're effectively impossible to search your codebase for, making it hard to review expressions that typically are much more likely to cause bugs.
Instead, in this case, if you actually need the full power of a C-style cast (disregarding const
ness at the moment), you should use reinterpret_cast<AICargo::TownEffect>
. Without looking at the code, though, it would not surprise me if a static_cast
were sufficient.
精彩评论