จุดประสงค์ของยูนารี“ +” ก่อนการเรียกไปยังสมาชิก std :: numeric_limits <unsigned char> คืออะไร


130

ฉันเห็นตัวอย่างนี้ในเอกสารของ cppreference สำหรับstd::numeric_limits

#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()

ฉันได้ทดสอบแล้วแทนที่ด้วย "-" และได้ผลเช่นกัน การใช้โอเปอเรเตอร์ "+" ดังกล่าวคืออะไร?


3
ลองมัน. คุณจะได้อะไรถ้าคุณละทิ้ง+?
Pete Becker

4
คำถามนี้ไม่จำเป็นต้องถามผู้เขียนหากผู้เขียนโค้ดใส่ใจที่จะอธิบายความหมายหรือใช้การแคสต์ที่ชัดเจนแทน ...
user202729

หากคุณแทนที่ด้วย-ผลลัพธ์จะไม่ใช่ค่าที่ถูกต้องสำหรับขีด จำกัด
phuclv

1
สำหรับบันทึกหากคุณต้องการให้ Google เป็นแบบนี้ในตัวเองสิ่งนี้เรียกว่าโอเปอเรเตอร์ "unary plus" ซึ่งเป็นค่าเดียวเพราะใช้ค่าเดียว (ในกรณีนี้คือสิ่งที่ตามมา) และ "plus "เป็นวิธีที่เหมาะกับ Google +ที่จะบอกว่า ในกรณีนี้ข้อความค้นหาของคุณอาจเป็น "c ++ unary plus" มัน ... ไม่ง่ายอย่างแน่นอนและคุณยังต้องเรียนรู้ที่จะอ่านเอกสารที่คุณจะพบ แต่ IMO เป็นทักษะที่มีประโยชน์ในการฝึกฝน
คดีของ Fund Monica

คำตอบ:


137

ผู้ประกอบการส่งออก<<เมื่อมีการผ่านchar(ลงนามหรือไม่ได้ลงนาม) จะเขียนเป็นตัวอักษร

unsigned charฟังก์ชั่นเหล่านั้นจะกลับค่าจากประเภท และตามที่ระบุไว้ข้างต้นว่าจะพิมพ์อักขระที่ค่าเหล่านั้นแสดงในการเข้ารหัสปัจจุบันไม่ใช่ค่าจำนวนเต็ม

+ประกอบการแปลงunsigned charกลับโดยฟังก์ชันเหล่านั้นไปยังintผ่านโปรโมชั่นจำนวนเต็ม ซึ่งหมายความว่าค่าจำนวนเต็มจะถูกพิมพ์แทน

การแสดงออกเหมือนเป็นหลักเท่ากับ+std::numeric_limits<unsigned char>::lowest()static_cast<int>(std::numeric_limits<unsigned char>::lowest())


37

+อยู่ที่นั่นเพื่อเปลี่ยนunsigned charเป็นintไฟล์. ตัว+ดำเนินการคือการรักษามูลค่า แต่มีผลในการกระตุ้นให้เกิดการส่งเสริมแบบรวมในตัวถูกดำเนินการ เพื่อให้แน่ใจว่าคุณเห็นค่าตัวเลขแทนที่จะเป็นอักขระสุ่ม (กึ่ง) บางตัวที่operator <<จะพิมพ์เมื่อกำหนดประเภทอักขระ


18

เพียงเพื่อเพิ่มการอ้างอิงถึงคำตอบที่ให้ไปแล้ว จากร่างมาตรฐานการทำงาน CPP N4713 :

8.5.2.1 ตัวดำเนินการยูนารี
...

  1. ตัวถูกดำเนินการของตัวดำเนินการ unary + จะต้องมีการคำนวณทางคณิตศาสตร์การแจงนับที่ไม่ได้กำหนดขอบเขตหรือชนิดตัวชี้และผลลัพธ์คือค่าของอาร์กิวเมนต์ อินทิกรัลโปรโมชั่นดำเนินการบนอินทิกรัลหรือการแจงนับ ประเภทของผลลัพธ์คือชนิดของตัวถูกดำเนินการที่เลื่อนขั้น

และchar, short, intและlongประเภทหนึ่ง


12

หากไม่มี+ผลลัพธ์จะแตกต่างกัน ข้อมูลโค้ดต่อไปนี้จะส่งออกa 97แทนa a

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

เหตุผลเป็นเพราะoverloads ที่แตกต่างกันพิมพ์ข้อมูลประเภทต่างๆ ไม่มีการbasic_ostream& operator<<( char value );โอเวอร์โหลดstd::basic_ostreamและอธิบายไว้ในตอนท้ายของหน้า

อาร์กิวเมนต์สตริงอักขระและอักขระ (เช่นประเภทcharหรือconst char*) ถูกจัดการโดยการโอเวอร์โหลดที่ไม่ใช่สมาชิกของoperator<<. ความพยายามที่จะเอาท์พุทของตัวละครโดยใช้ไวยากรณ์ฟังก์ชันสมาชิกโทร (เช่นstd::cout.operator<<('c');) จะเรียกหนึ่ง overloads (2-4) และผลผลิตค่าตัวเลข การพยายามส่งออกสตริงอักขระโดยใช้ไวยากรณ์การเรียกฟังก์ชันสมาชิกจะเรียกโอเวอร์โหลด (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 +นั่นเป็นหนึ่งในโปรแกรมที่มีประโยชน์ที่หายากของผู้ประกอบการบวกเอก การแคสต์ที่ชัดเจนintจะใช้งานได้เช่นกัน

มีหลายคนที่ประสบปัญหาใน SO เช่น


1
คุณหมายถึงยูนารีบวกไม่ใช่ลบ?
Ruslan
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.