11

次の動作の理由は何ですか?

class BoolWrapper
{
public:
    BoolWrapper(bool value) : value(value) {}

    operator bool() const { return value; }
    operator int() const { return (int) value; }

private:
    bool value;
};


BoolWrapper bw(true);

if (bw) { ... }            // invokes operator bool()
if (bw == true) { ... }    // invokes operator int() -- why?

この動作は予期されたものですか? (GCC 4.7.2 を使用)

4

3 に答える 3

6

5/9から:

算術型または列挙型のオペランドを想定する多くの二項演算子は、同様の方法で変換を行い、結果の型を生成します。目的は、結果の型でもある共通の型を生成することです。このパターンは通常の算術変換と呼ばれ、次のように定義されます。

[重要ではないいくつかの浮動小数点アイテム。]

それ以外の場合、両方のオペランドで整数昇格 (4.5) が実行されます。

そして 3.9.1/6 から、bool が整数昇格の対象となることがわかります。

bool 型の値は、true または false のいずれかです。] 以下で説明するように、bool 値は整数型として動作します。bool 型の値は、整数昇格 (4.5) に参加します。

于 2012-11-06T16:12:53.877 に答える
6

あなたの期待は、言語が 2 つの値を比較する方法を既に知っているというあなたの信念に基づいていboolます。実際にはそうではありませんが、驚くべきことに聞こえるかもしれません。より正確には、言語はそれを直接行う方法を「知りません」。

概念レベルでは、C++ には比較専用の組み込み等値比較演算子がありませんbool vs. bool。コードを記述true == falseしても、実際には言語によって として解釈され(int) true == (int) falseます。への暗黙的な変換は、通常の算術変換intの規則によって導入され、その後で比較が使用されます。int vs. int

bool2 つの値を比較できる最も直接的な組み込み演算子は、比較用の演算子ですint vs. int。これは、コンパイラがあなたのケースでも使用しようとしている演算子です。char vs. charとのshort vs. short比較にはまったく同じ演算子が使用されます。

つまり、コンパイラが式boolで変換演算子を使用できる唯一の方法は、次のようにすることです。bw == true

(int)(bool) bw == (int) true

これは確かに直接よりも「最適」ではありません

(int) bw == (int) true

これは、後者のバリアントを選択するように言語を駆動するロジックです。

于 2012-11-06T16:33:25.977 に答える
4

最初のケースでは、if句がbool条件を想定しているため、これが選択された変換です。

BoolWrapper2 番目のケースでは、 aとa の比較を求めていboolます。それを行うためのoperator ==オーバーロードが存在しないため、コンパイラはこれらの引数を適切なものに変換する必要があります。標準 (セクション 4.5、整数プロモーション) によると、変換に推奨される整数型は ですintBoolWrapperとの両方boolが に変換できるためint、これが選択された変換です。

于 2012-11-06T16:13:05.180 に答える