2011-09-26 47 views
14

Tôi đang làm việc trên một chương trình C++ cho lớp học, và trình biên dịch của tôi đang phàn nàn về một cuộc gọi hàm "không rõ ràng". Tôi nghi ngờ rằng điều này là bởi vì có một số chức năng được xác định với các thông số khác nhau.Làm thế nào để sửa một cuộc gọi hàm "không rõ ràng"?

Làm cách nào tôi có thể cho trình biên dịch biết tôi muốn trình biên dịch nào? Ngoài việc khắc phục sự cố cụ thể, có quy tắc chung nào, chẳng hạn như typecasting, có thể giải quyết các loại vấn đề này không?

Edit:

Trong trường hợp của tôi, tôi đã cố gắng gọi abs() bên trong một tuyên bố cout, đi qua trong hai double s.

cout << "Amount is:" << abs(amountOrdered-amountPaid);

Edit2:

tôi bao gồm ba tiêu đề sau đây:

#include <iostream> 
#include <fstream> 
#include <iomanip> 

using namespace std; 

Edit3:

Tôi đã hoàn thành chương trình mà không cần mã này, nhưng vì lợi ích của việc theo dõi thông qua nhiệm vụ này trên, tôi đã sao chép vấn đề. Lỗi chính tả là:

Gọi tới 'abs' không rõ ràng.

Trình biên dịch cung cấp ba phiên bản abs, mỗi loại lấy một kiểu dữ liệu khác nhau làm tham số.

+1

Bạn vui lòng hiển thị ví dụ từ mã của bạn? –

+1

Nó thực sự phụ thuộc vào tình hình. Bạn cần đăng mã và nếu lỗi trình biên dịch bao gồm các hàm nào là các ứng cử viên (các GCC gần đây làm) cũng giúp ích. –

+2

Cũng tốt sẽ là tiêu đề được bao gồm. – mkb

Trả lời

19

gì xảy ra là bạn đã bao gồm <cstdlib> (gián tiếp, vì nó được bao gồm bởi iostream) cùng với using namespace std;. Tiêu đề này khai báo hai hàm trong std với tên abs(). Một người mất và trả về long long và người kia trả về long. Ngoài ra, có một trong không gian tên chung (trả về int) xuất phát từ <stdlib.h>.

Để khắc phục: tốt, số abs() phải mất gấp đôi là trong <cmath> và điều đó thực sự sẽ cung cấp cho bạn câu trả lời bạn muốn!

+4

TL; DR: tránh 'sử dụng không gian tên'. –

+0

@MatthieuM., Tôi đã thấy lỗi này (sematic) ngay cả khi sử dụng 'std :: abs()' trong iOS SDK. Lỗi đã bị xóa khi tôi xóa 'std ::' và chỉ sử dụng 'abs()'. – iammilind

+1

Vâng, vấn đề là do chuyển đổi loại số tự động. – mkb

-1

Không chắc tại sao điều này không gọi phiên bản int của abs nhưng bạn có thể thử loại đúc biểu thức (amountOrdered - amountPaid) như int tức

cout <<"Amount is: "<< abs((int)(amountOrdered - amountPaint)); 
+1

"Không chắc chắn tại sao điều này không gọi là phiên bản int của abs" Nó có thể gây ra 'amountOrdered' và' amountPaid' được tăng gấp đôi? –

+0

Bạn chính xác không chắc mình đang nghĩ gì! @OP trình biên dịch là nhầm lẫn mà phiên bản để gọi (dài hoặc đôi) bởi vì nó không chắc chắn nếu nó cần phải typecast để dài hoặc int từ đôi. Mr.R.Martinho - Tôi đoán giải pháp của tôi sẽ giúp trình biên dịch quyết định phiên bản nào cần gọi. Vì vậy, tôi phần nào đứng đúng :) –

4

Chức năng abs bao gồm <cstdlib> bị quá tải cho intlonglong long. Vì bạn đưa ra đối số double, trình biên dịch không phù hợp chính xác, do đó, nó cố gắng chuyển đổi double thành loại abs chấp nhận, nhưng không biết liệu nó có nên chuyển đổi thành int, long hay không long long, do đó nó không rõ ràng.

Nhưng bạn có thể thực sự muốn abs có số double và trả về số double. Đối với điều này, bạn cần phải bao gồm <cmath>.Vì đối số double khớp chính xác, trình biên dịch sẽ không phàn nàn.

Có vẻ như <cstdlib> được bao gồm tự động khi bạn bao gồm các tiêu đề khác không nên xảy ra. Trình biên dịch phải có error: ‘abs’ was not declared in this scope hoặc một cái gì đó tương tự.

+0

'abs' không phải là mẫu chức năng. Việc đưa ra một đối số mẫu sẽ không hoạt động. Một 'static_cast (thanh)' sẽ biên dịch (nhưng vẫn đưa ra một câu trả lời sai) – mkb

+0

@mkb - Cảm ơn, tôi quên chúng đơn giản là quá tải không phải là các đặc tả chức năng của mẫu. Đã chỉnh sửa phần đó. – JohnPS

2

Thử sử dụng fabs được xác định trong <cmath>. Phải mất float, doublelong double làm đối số. abs được xác định cả trong <cmath><cstdlib>. Sự khác biệt là abs(int), abs(long)abs(long long) được xác định trong <cstdlib> trong khi các phiên bản khác được xác định trong <cmath>.

+0

Một giải pháp phổ biến để khắc phục loại lỗi này là sử dụng phiên bản C++ của thư viện thay vì thư viện C chuẩn, ví dụ: cstdio thay vì stdio.h. Các libs C++ có tên với tiền tố 'c' và không '.h' – Andiana

Các vấn đề liên quan