操作は「false <true」で明確に定義されていますか?


153

C ++仕様は以下を定義していますか?

  1. ブール型パラメータの「小なり」演算子の存在。
  2. 4つのパラメーターの順列の結果?

つまり、次の操作の結果は仕様で定義されていますか?

false < false
false < true
true < false
true < true

私のセットアップ(Centos 7、gcc 4.8.2)では、以下のコードは私が期待するものを吐き出します(Cの履歴でfalseを0として、trueを1として表す):

false < false = false
false < true = true
true < false = false
true < true = false

ほとんどの(すべての)コンパイラーが同じ出力を出すと確信していますが、これはC ++仕様によって規定されていますか?または、難読化されていますが、仕様に準拠したコンパイラは、trueがfalseよりも小さいと判断できますか?

#include <iostream>

const char * s(bool a)
{
  return (a ? "true" : "false");
}

void test(bool a, bool b)
{
  std::cout << s(a) << " < " << s(b) << " = " << s(a < b) << std::endl;
}

int main(int argc, char* argv[])
{
  test(false, false);
  test(false, true);
  test(true, false);
  test(true, true);
  return 0;
}

6
@Ulterior有効な使用法があります。asとして使用std::minするstd::vector<bool>など&&
Angewは、2014

19
@UlteriorこれらのStackOverflowのすべての年月の後でまだ尋ねられていない良い質問を理解できる場合、いくつかのポイントに値します。それはトローリングではありません。
Mark Ransom 2014年

35
@Ulterior尋ねる動機は本物です。私はC ++にかなり慣れていない(Cから来ている)ため、いくつかのオブジェクトをstd :: set <>に格納したいと考えています。オブジェクトの<演算子の実装は、主にオブジェクトのブールプロパティに基づいており、その後に他の2次識別プロパティが続きます。セットを繰り返し処理するときは、「false」オブジェクトが最初に来るようにしたいと思います。ここでは今でも機能しますが、オブジェクトの<での(a?1:0)などの使用に不必要に頼ることなく、プラットフォーム(埋め込みのものを含む)全体で機能することが保証される安心を探しています。オペレーター。
ダンカン2014年

26
乱す結果は、あるp <= q手段p implies qときpqbool型です!
セオドアNorvell 2014年

4
@Technophileおそらく邪魔なのは、<=誤って左矢印として読み取られる可能性があり、「のみの場合」(つまり、「[実質的に]が意味する」)右矢印がタイプセットまたは非公式に書かれる=>(つまり、二重シャフトが似ている=)ことです。 。左向き矢印は「if」として読み取られることさえありますが、これは「のみ」の右向き矢印を使用するよりもはるかに一般的ではないと思います。
Eliah Kagan 14年

回答:


207

TL; DR:

操作はドラフトC ++標準に従って明確に定義されています。

細部

C ++の標準セクションの5.9 関係演算子のドラフトに移動すると、次のように表示されます(強調今後の予定です)。

オペランドは、算術有するもの、列挙、またはポインタ、または型のstd :: nullptr_tを。演算子<(以下)、>(以上)、<=(以下)、および> =(以上)はすべてfalseまたはtrueを返します。結果のタイプはブールです

boolは3.9.1からの算術型であり、基本型

bool型、char 型、char16_t型、char32_t型、wchar_t型、および符号付き整数型と符号なし整数型は、まとめて整数型 と呼ばれます。

そして

整数型と浮動小数点型はまとめて算術型と呼ばれます。

そして、trueしてfalseからbooleanリテラル2.14.6ブールリテラル:

boolean-literal:
    false
    true

セクション5.9に戻り、関係演算子のメカニズムをさらに確認すると、次のようになります。

通常の算術変換は、算術型または列挙型のオペランドに対して実行されます。

通常の算術変換はセクションで説明されている5と言いました。

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

そしてセクション4.5は言う:

bool型のprvalueはint型のprvalueに変換でき、falseはゼロになり、trueは1になります。

そして式:

false < false
false < true
true < false
true < true

これらのルールを使用すると、次のようになります。

0 < 0
0 < 1
1 < 0
1 < 1

6
いいですね、それはどんな答えでもあり得るのと同じくらい明白でありながら、まだ読みやすいです。nit:私はあなたが間違った「型」を太字にしたと思います:「オペランドは算術、列挙、またはポインタ、または型std :: nullptr_tを持つ必要があります。」わかりやすくするために括弧を追加すると、((算術、列挙、またはポインタ)タイプ)または(タイプstd :: nullptr_t)が得られます。

それはあなたの答えを変えるわけではありませんが、N3485 [over.built] / 12:プロモートされた算術型LとRのすべてのペアについて、次の形式の候補演算子関数が存在します... bool operator <(L、R); -あなたが引用したルールが適用される前に議論が促進されていませんか?
クリス

@chris私はそのセクションに精通していないので、私はそれについて考えなければならないでしょうが、答えが私が見ることができるものから変化するとは思いません。
Shafik Yaghmour 2015年

ええ、プロモーションはどちらにしても最初に起こることです。
クリス2015年

63

ブール値は、falseとして定義され0trueとして定義された通常の整数の昇格の対象となり1ます。これにより、すべての比較が明確になります。


2
...および関係演算子は、算術型または列挙型のオペランドに対して通常の算術変換(整数の昇格を含む)を実行するように指定されます。
TC

5
私、この答えはShafikのより短いですが、私は重要なポイントだと思うようなfalseのように定義される0trueのように定義された1 標準で(だけではなく一般的な方法では)それをバックアップする証拠を必要とします。
KRyan 2014年

@KRyan何、あなたはそれを私の言葉にしないでしょうか?:) boolタイプが存在する前、C ++が存在する前は、ブール演算の結果は0falseおよび1true として定義されていました。K + Rで見つけられても驚かないでしょう。
Mark Ransom 2014年

1
@KRyan K + Rまで戻ることはできませんが、1990 ANSI C規格のコピーを探しました。6.3.8項では、「指定された関係がtrueの場合、演算子<(以下)、>(より大きい)、<=(以下)、および>=(以上)は1を返し、そうであれば0を返します。false。結果のタイプはintです。 "
Mark Ransom 2014年

1
IIRCの最大の問題は、K&Rではenum bool { false = 0, true = 1}合法だったが、を定義していなかったことoperator<です。
MSalters 2014年

22

C ++標準に準拠(5.9関係演算子)

2通常の算術変換は、算術型または列挙型のオペランドで実行されます。

そして

1 ...結果のタイプはブールです。

および(3.9.1基本タイプ)

6 bool型の値は、trueまたはfalseです。49[注:符号付き、符号なし、短い、または長いbool型または値はありません。—end note] タイプboolの値は、整数昇格(4.5)に参加します。

および(4.5統合プロモーション)

6 bool型のprvalueは、int型のprvalueに変換できます。falseは0になり、trueは1になります

したがって、すべての例で、trueはint 1に変換され、falseはint 0に変換されます

これらの表現

false < false
false < true
true < false
true < true

完全に等しい

0 < 0
0 < 1
1 < 0
1 < 1

8

ブール値falseはと同等int 0で、ブール値trueはと同等int 1です。したがって、これは、式false < true=> 0 < 1が返す唯一の式である理由を説明していますtrue

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.