私は見ました std::numeric_limits
に関するcppreferenceのドキュメントのこの例
#include <limits>
#include <iostream>
int main()
{
std::cout << "type\tlowest()\tmin()\t\tmax()\n\n";
std::cout << "uchar\t"
<< +std::numeric_limits<unsigned char>::lowest() << '\t' << '\t'
<< +std::numeric_limits<unsigned char>::min() << '\t' << '\t'
<< +std::numeric_limits<unsigned char>::max() << '\n';
std::cout << "int\t"
<< std::numeric_limits<int>::lowest() << '\t'
<< std::numeric_limits<int>::min() << '\t'
<< std::numeric_limits<int>::max() << '\n';
std::cout << "float\t"
<< std::numeric_limits<float>::lowest() << '\t'
<< std::numeric_limits<float>::min() << '\t'
<< std::numeric_limits<float>::max() << '\n';
std::cout << "double\t"
<< std::numeric_limits<double>::lowest() << '\t'
<< std::numeric_limits<double>::min() << '\t'
<< std::numeric_limits<double>::max() << '\n';
}
の "+"演算子は理解できません
<< +std::numeric_limits<unsigned char>::lowest()
私はそれをテストし、 " - "に置き換えました、そしてそれもまたうまくいきました。そのような「+」演算子の使用は何ですか?
出力演算子<<
は、char
(符号付きまたは符号なし)を渡されると、文字として書きます。
これらの関数はunsigned char
型の値を返します。そして上記のように、それらの値が現在のエンコーディングで表す文字を表示します。それらの整数値は表示しません。
+
演算子は、これらの関数によって返されるunsigned char
を 整数の昇格 に変換してint
に変換します。これは、整数値が代わりに表示されることを意味します。
+std::numeric_limits<unsigned char>::lowest()
のような式は、基本的にstatic_cast<int>(std::numeric_limits<unsigned char>::lowest())
と同じです。
+
はunsigned char
をint
に変換するためにあります。 +
演算子は値を保持しますが、オペランドに整数の昇格を引き起こす効果があります。 operator <<
が文字タイプを与えられたときに表示する(半)ランダムな文字の代わりにあなたが確実に数値を見るようにするためです。
すでに与えられた答えへの参照を追加するためだけに。 CPP標準ワーキングドラフトから N471 :
8.5.2.1単項演算子
...
- 単項演算子+のオペランドは算術型、スコープなしの列挙型、またはポインタ型でなければならず、結果は引数の値です。 整数昇格は、整数オペランドまたは列挙型オペランドで実行されます。結果の型は、昇格されたオペランドの型です。
char
、short
、int
、およびlong
は整数型です。
+
がないと、結果は異なります。次のスニペットは、a 97
の代わりにa a
を出力します。
char ch = 'a';
std::cout << ch << ' ' << +ch << '\n';
その理由は、オーバーロードが異なると、異なる種類のデータが出力されるためです。 std::basic_ostream
に対するbasic_ostream& operator<<( char value );
のオーバーロードはありません、そしてそれはページの終わりに説明されています
文字や文字列の引数(例えば
char
やconst char*
型)は、operator<<
の 非メンバオーバーロード によって処理されます。メンバ関数呼び出し構文(例:std::cout.operator<<('c');
)を使用して文字を出力しようとすると、overload(2-4)のいずれかが呼び出され、数値が出力されます。メンバ関数呼び出し構文を使って文字列を出力しようとすると、overload(7)が呼び出され、代わりにポインタ値が表示されます。
char
変数を渡すときに呼び出される 非メンバーオーバーロード は、
template< class CharT, class Traits> basic_ostream<CharT,Traits>& operator<<(
basic_ostream<CharT,Traits>& os, char ch );
コードポイントch
にある文字を出力します。
そのため、基本的にchar
、signed char
、またはunsigned char
をストリームに直接渡すと、文字が出力されます。上記の行の+
を削除しようとすると、それは期待していないものである "奇妙な"あるいは見えない文字を表示することがわかります。
代わりにそれらの数値が必要な場合は、short
、int
、long
またはlong long
のオーバーロードを呼び出す必要があります。これを行う最も簡単な方法は、単項プラス+
を使用してchar
からint
にプロモートすることです。これは 単項プラス演算子 の まれに役立つアプリケーション の1つです。 int
への明示的なキャストも有効です。
SOのような問題に直面している人はたくさんいます