Mục đích của một đơn vị + + unary trước khi gọi thành viên std :: num_limits <unsign char> là gì?


130

Tôi đã thấy ví dụ này trong tài liệu của cppreference chostd::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';
}

Tôi không hiểu toán tử "+" trong

<< +std::numeric_limits<unsigned char>::lowest()

Tôi đã thử nó, thay thế nó bằng "-", và nó cũng hoạt động. Việc sử dụng toán tử "+" như vậy là gì?


3
Thử nó. Bạn nhận được gì nếu bạn rời khỏi +?
Pete Becker

4
Câu hỏi này sẽ không cần phải hỏi nếu người viết mã quan tâm giải thích ý nghĩa của nó hoặc sử dụng một diễn viên rõ ràng thay thế ...
user202729

nếu bạn thay thế bằng -thì các đầu ra sẽ không phải là giá trị chính xác cho các giới hạn
phuclv

1
Đối với bản ghi, nếu bạn muốn Google loại điều này trong chính mình, đây được gọi là toán tử "unary plus" - nó đơn nhất bởi vì nó có một giá trị duy nhất (trong trường hợp này là thứ ngay sau nó) và "cộng "Là cách nói thân thiện với Google +. Trong trường hợp này, truy vấn của bạn có thể là "c ++ unary plus". Nó ... không chính xác trực quan và bạn vẫn phải học cách đọc tài liệu mà bạn sẽ tìm thấy, nhưng IMO đó là một kỹ năng hữu ích để trau dồi.
Vụ kiện của Quỹ Monica

Câu trả lời:


137

Toán tử đầu ra <<khi được thông qua char(đã ký hoặc chưa ký) sẽ viết nó dưới dạng một ký tự .

Những hàm này sẽ trả về giá trị của kiểu unsigned char. Và như đã lưu ý ở trên sẽ in các ký tự mà các giá trị đại diện trong mã hóa hiện tại, không phải các giá trị nguyên của chúng.

Các +cải khai thác các unsigned chartrả về bởi những chức năng để một intthông qua chương trình khuyến mãi số nguyên . Có nghĩa là các giá trị nguyên sẽ được in thay thế.

Một biểu thức như +std::numeric_limits<unsigned char>::lowest()về cơ bản là bằng static_cast<int>(std::numeric_limits<unsigned char>::lowest()).


37

+là có để biến unsigned charthành một int. Các +nhà điều hành là giá trị bảo tồn, nhưng nó có tác dụng gây xúc tiến không thể thiếu trên toán hạng của nó. Để đảm bảo bạn thấy một giá trị số thay vì một số ký tự ngẫu nhiên (bán) operator <<sẽ in khi được cung cấp một loại ký tự.


18

Chỉ cần thêm một tài liệu tham khảo cho các câu trả lời đã được đưa ra. Từ dự thảo làm việc tiêu chuẩn CPP N4713 :

8.5.2.1 Toán tử đơn nguyên
...

  1. Toán hạng của toán tử unary + phải có số học, liệt kê không theo tỷ lệ hoặc loại con trỏ và kết quả là giá trị của đối số. Xúc tiến tích phân được thực hiện trên các toán hạng tích phân hoặc liệt kê. Loại kết quả là loại toán hạng được thăng cấp.

char, short, int, và longlà loại không thể thiếu.


12

Nếu không có +kết quả sẽ khác. Các đầu ra đoạn mã sau a 97thay vìa a

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

Lý do là vì quá tải khác nhau in các loại dữ liệu khác nhau . Không có basic_ostream& operator<<( char value );quá tải cho std::basic_ostreamvà nó được giải thích ở cuối trang

Các đối số chuỗi ký tự và ký tự (ví dụ: loại charhoặc const char*) được xử lý bởi quá tải không phải thành viên của operator<<. Cố gắng xuất một ký tự bằng cú pháp gọi hàm thành viên (ví dụ std::cout.operator<<('c');:) sẽ gọi một trong các tình trạng quá tải (2-4) và xuất giá trị số . Cố gắng xuất chuỗi ký tự bằng cú pháp gọi hàm thành viên sẽ gọi quá tải (7) và in giá trị con trỏ thay thế.

Các tình trạng quá tải không thành viên đó sẽ được gọi khi bạn vượt qua một charbiến là

template< class CharT, class Traits> basic_ostream<CharT,Traits>& operator<<(
    basic_ostream<CharT,Traits>& os, char ch );

trong đó in ra các nhân vật tại điểm mã ch

Vì vậy, về cơ bản nếu bạn vượt qua char, signed charhoặc unsigned chartrực tiếp đến luồng, nó sẽ in ký tự ra. Nếu bạn thử xóa các +dòng trên, bạn sẽ thấy rằng nó in một số ký tự "lạ" hoặc không nhìn thấy được, đó không phải là điều người ta mong đợi

Nếu bạn muốn các giá trị số của họ thay vào đó bạn phải gọi tình trạng quá tải cho short, int, longhoặc long long. Cách dễ nhất để làm điều này là quảng bá từ charđến intvới unary plus +. Đó là một trong những ứng dụng hữu ích hiếm có của toán tử unary plus . Một diễn viên rõ ràng intcũng sẽ làm việc

Có nhiều người phải đối mặt với vấn đề đó trên SO như


1
Ý của bạn là unary cộng , không trừ?
Ruslan
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.