Câu trả lời:
Trong C ++, nó luôn đủ để sử dụng std::abs
; nó bị quá tải đối với tất cả các loại số.
Trong C, abs
chỉ hoạt động trên số nguyên và bạn cần fabs
giá trị dấu phẩy động. Chúng có sẵn trong C ++ (cùng với tất cả thư viện C), nhưng không cần phải sử dụng chúng.
int
phiên bản từ thư viện C, có quá tải cho long
, float
, double
và long double
. Mệnh đề 26.2.7 cũng định nghĩa quá tải cho complex
.
std::
và chỉ sử dụng abs
, mã của bạn sẽ hoạt động như mong đợi trên windows nhưng sẽ sử dụng int
phiên bản trên linux, có thể rất khó gỡ lỗi.
Vẫn có thể sử dụng đối số fabs
for double
và float
. Tôi thích điều này hơn vì nó đảm bảo rằng nếu tôi vô tình loại bỏ dấu std::
hiệu abs
, hành vi vẫn giữ nguyên đối với các đầu vào dấu chấm động.
Tôi vừa dành 10 phút để gỡ lỗi vấn đề này, do lỗi của chính tôi khi sử dụng abs
thay vì std::abs
. Tôi giả định rằng điều đó using namespace std;
sẽ suy ra std::abs
nhưng nó không xảy ra, và thay vào đó là sử dụng phiên bản C.
Dù sao, tôi tin rằng việc sử dụng fabs
thay vì abs
cho đầu vào dấu phẩy động là một cách tốt để ghi lại ý định của bạn một cách rõ ràng.
std::abs
dường như luôn được gọi (và không phải phiên bản C của abs
) khi gọi abs
miễn là using namespace std;
được giải thích ở bắt đầu. Tôi không biết liệu đây có phải là trình biên dịch cụ thể hay không.
Có một lý do nữa để đề xuất std::fabs
cho các đầu vào dấu phẩy động một cách rõ ràng.
Nếu bạn quên bao gồm <cmath>, bạn std::abs(my_float_num)
có thể std::abs(int)
thay thế bằng std::abs(float)
. Thật khó để nhận thấy.
"abs" và "fabs" chỉ giống nhau đối với các kiểu float của C ++, khi chúng có thể được dịch mà không có thông báo quá tải không rõ ràng.
Tôi đang sử dụng g ++ (g ++ - 7). Cùng với việc sử dụng mẫu và đặc biệt là khi sử dụng mpreal, có những trường hợp có thông báo "quá tải không rõ ràng" - abs(static_cast<T>(x))
không phải lúc nào cũng giải quyết được điều đó. Khi cơ bụng không rõ ràng, có khả năng fabs đang hoạt động như mong đợi. Đối với sqrt, tôi không tìm thấy lối thoát nào đơn giản như vậy.
Kể từ nhiều tuần tôi đang vật lộn với C ++ "không tồn tại vấn đề". Tôi đang cập nhật một chương trình C ++ cũ lên C ++ 14 để sử dụng nhiều hơn và tốt hơn so với trước đây. Thường thì cùng một tham số mẫu có thể là thực tế bất kỳ kiểu float chuẩn hoặc kiểu phức tạp hoặc kiểu lớp. Tại sao từ trước đến nay, đôi dài hành động có phần hợp lý hơn các loại khác. Tất cả đều hoạt động, và tôi đã bao gồm cả mpreal trước đây. Sau đó, tôi đang đặt loại float mặc định của mình thành mpreal và gặp phải vô số lỗi cú pháp. Điều đó đã tạo ra hàng nghìn lần quá tải không rõ ràng, ví dụ như abs và sqrt, kêu gọi các giải pháp khác nhau. Một số cần các chức năng trợ giúp quá tải nhưng nằm ngoài khuôn mẫu. Phải thay thế riêng lẻ một nghìn lần sử dụng 0,0L và 1,0L bằng loại hằng số chính xác sử dụng Zero hoặc One hoặc type_cast - định nghĩa chuyển đổi tự động là không thể vì không rõ ràng.
Cho đến tháng 5, tôi nhận thấy sự tồn tại của các chuyển đổi ngầm rất tốt. Nhưng đơn giản hơn nhiều sẽ không có bất kỳ, và có các hằng số lưu kiểu với type_cast rõ ràng an toàn cho bất kỳ kiểu hằng số tiêu chuẩn nào khác.