2016-08-29 4 views
13

この質問は、私がthis earlier, intriguing question about C-style casts and type conversionsと答えるときにC++仕様で気づいたことに関係しています。C++仕様では、Cスタイルのキャストで使用するstatic_cast/const_castチェーンでタイプを選択する方法が示されていますか?

C++仕様では、§ 5.4のCスタイルのキャストについて説明しています。これは、1つが有効であることが判明するまで、キャスト表記は、この順序で、以下のキャストをしようとしますと言っている:const_cast

  • reinterpret_cast
  • reinterpret_cast続い

    • const_cast
    • static_cast
    • static_cast次にconst_castが続きます。

    私はそれがconst_cast続いstatic_castを使用することを意味するものの偉大な直感的なアイデアを持っているが(例えば、const_cast<Base*>(static_cast<const Base*>(expr))を経てBase*からconst Derived*を変換する)、私は、任意の文言が表示されません具体的には、具体的には、static_cast/const_castシリーズで使用されているタイプが推測されます。単純なポインタの場合はそれほど難しくはありませんが、リンクされた質問に見られるように、余分なconstがある場所に導入され、別の場所で取り除かれると、キャストが成功する可能性があります。

    コンパイラーがどのような型をキャスティングチェーンで使用するかを決定するための規則はありますか?もしそうなら、彼らはどこですか?そうでない場合は、これが言語上の欠陥か、試してみる可能性のあるすべてのキャストを一意に決定するための十分な暗黙のルールがありますか?

  • 答えて

    3

    もしそうでなければ、これは言語上の欠陥ですか、試してみる可能性のあるすべてのキャストを一意に決定するのに十分な暗黙のルールがありますか?

    const_cast、つまりすべての「中間タイプ」のみを使用してターゲットタイプにキャストできるすべてのタイプを構築することはどうですか? static_castが動作しない場合は、ターゲットタイプT考える

    、1は、結果の型がconst_cast によってTにキャストバックすることができるようにCV-修飾子を追加することができ、すべての位置を特定します。アルゴリズムのスケッチ:cv分解([conv.qual]/1)をTとする。それぞれcvjを追加することができます。 Tが参考になっている場合は、レフェリータイプのcv-qualificationを追加することができます。

    ここにこれらのすべての場所にconst volatileを追加します。結果のタイプCTを呼び出します。代わりに式static_castCTに試してください。それが成功すれば、キャストチェーンはconst_cast<T>(static_cast<CT>(e))です。

    static_castに続いてconst_castを使用して変換されていない可能性があります(これは私が持っているが、この質問ではない)。しかし、ブルートフォースを使ってconst/volatileを繰り返し削除し、本当に欲しければそれぞれのタイプをチェックすることができます。したがって、理論的にはあいまいさや不一致はありません。いくつかのキャストチェーンがある場合は、それを決定することができます。実際には、Tから構築できる「最も認定された」型が(確かに)十分であるため、アルゴリズムは非常に簡単にできます。

    関連する問題