web-dev-qa-db-ja.com

std :: numeric_limits <unsigned char>メンバーを呼び出す前の単項「+」の目的は何ですか?

私は見ました 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()

私はそれをテストし、 " - "に置き換えました、そしてそれもまたうまくいきました。そのような「+」演算子の使用は何ですか?

127
Zhang

出力演算子<<は、char(符号付きまたは符号なし)を渡されると、文字として書きます。

これらの関数はunsigned char型の値を返します。そして上記のように、それらの値が現在のエンコーディングで表す文字を表示します。それらの整数値は表示しません。

+演算子は、これらの関数によって返されるunsigned char整数の昇格 に変換してintに変換します。これは、整数値が代わりに表示されることを意味します。

+std::numeric_limits<unsigned char>::lowest()のような式は、基本的にstatic_cast<int>(std::numeric_limits<unsigned char>::lowest())と同じです。

135

+unsigned charintに変換するためにあります。 +演算子は値を保持しますが、オペランドに整数の昇格を引き起こす効果があります。 operator <<が文字タイプを与えられたときに表示する(半)ランダムな文字の代わりにあなたが確実に数値を見るようにするためです。

37
StoryTeller

すでに与えられた答えへの参照を追加するためだけに。 CPP標準ワーキングドラフトから N471

8.5.2.1単項演算子
...

  1. 単項演算子+のオペランドは算術型、スコープなしの列挙型、またはポインタ型でなければならず、結果は引数の値です。 整数昇格は、整数オペランドまたは列挙型オペランドで実行されます。結果の型は、昇格されたオペランドの型です。

charshortint、およびlongは整数型です。

18
P.W

+がないと、結果は異なります。次のスニペットは、a 97の代わりにa aを出力します。

char ch = 'a';
std::cout << ch << ' ' << +ch << '\n';

その理由は、オーバーロードが異なると、異なる種類のデータが出力されるためですstd::basic_ostream に対するbasic_ostream& operator<<( char value );のオーバーロードはありません、そしてそれはページの終わりに説明されています

文字や文字列の引数(例えばcharconst 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にある文字を出力します。

そのため、基本的にcharsigned char、またはunsigned charをストリームに直接渡すと、文字が出力されます。上記の行の+を削除しようとすると、それは期待していないものである "奇妙な"あるいは見えない文字を表示することがわかります。

代わりにそれらの数値が必要な場合は、shortintlongまたはlong longのオーバーロードを呼び出す必要があります。これを行う最も簡単な方法は、単項プラス+を使用してcharからintにプロモートすることです。これは 単項プラス演算子まれに役立つアプリケーション の1つです。 intへの明示的なキャストも有効です。

SOのような問題に直面している人はたくさんいます

12
phuclv