简体   繁体   中英

Does the C++ specification say how types are chosen in the static_cast/const_cast chain to be used in a C-style cast?

This question concerns something I noticed in the C++ spec when I was trying to answer this earlier, intriguing question about C-style casts and type conversions .

The C++ spec talks about C-style casts in §5.4. It says that the cast notation will try the following casts, in this order, until one is found that is valid:

  • const_cast
  • static_cast
  • static_cast followed by const_cast
  • reinterpret_cast
  • reinterpret_cast followed by const_cast .

While I have a great intuitive idea of what it means to use a static_cast followed by a const_cast (for example, to convert a const Derived* to a Base* by going through a const_cast<Base*>(static_cast<const Base*>(expr)) ), I don't see any wording in the spec saying how, specifically, the types used in the static_cast / const_cast series are to be deduced. In the case of simple pointers it's not that hard, but as seen in the linked question the cast might succeed if an extra const is introduced in one place and removed in another.

Are there any rules governing how a compiler is supposed to determine what types to use in the casting chain? If so, where are they? If not, is this a defect in the language, or are there sufficient implicit rules to uniquely determine all the possible casts to try?

If not, is this a defect in the language, or are there sufficient implicit rules to uniquely determine all the possible casts to try?

What about constructing all types that can be cast to the target type using only const_cast , ie all "intermediate types"?

Given target type T , if static_cast doesn't work, identify all positions where one could add cv-qualifiers such that the resulting type can be cast back to T by const_cast 1 . Sketch of the algorithm: take the cv-decomposition ( [conv.qual]/1 ) of T ; each cv j can be augmented. If T is a reference, we can augment the referee type's cv-qualification.

Now add const volatile to all these places. Call the resulting type CT . Try static_cast ing the expression to CT instead. If that works, our cast chain is const_cast<T>(static_cast<CT>( e )) .

If this doesn't work, there very probably is no conversion using static_cast followed by const_cast (I haven't delved into the deep corners of overload resolution (well I have, but not for this question)). But we could use brute force to repeatedly remove const / volatile s and check each type if we really wanted. So in theory, there is no ambiguity or underspecification; if there is some cast chain, it can be determined. In practice, the algorithm can be made very simple, because the "most cv-qualified" type we can construct from T is (assuredly) sufficient.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM