2011-01-12 52 views
16

Thông báo lỗi này có ý nghĩa gì?Cuộc gọi của chức năng quá tải là mơ hồ

error: call of overloaded ‘setval(int)’ is ambiguous 
huge.cpp:18: note: candidates are: void huge::setval(unsigned int) 
huge.cpp:28: note:     void huge::setval(const char*) 

Mã của tôi trông như thế này:

#include <iostream> 
#define BYTES 8 
using namespace std ; 

class huge { 
private: 
    unsigned char data[BYTES]; 
public: 
    void setval(unsigned int); 
    void setval(const char *); 
}; 

void huge::setval(unsigned int t) { 
    for(int i = 0; i< BYTES ; i++) { 
     data[i] = t; 
     t = t >> 1; 
    } 
} 

void huge::setval(const char *s) { 
    for(int i = 0; i< BYTES ; i++) 
     data[i] = s[i]; 
} 

int main() { 
    huge p; 
    p.setval(0); 
    return 0; 
} 
+4

Tôi đoán câu trả lời cho câu hỏi này sẽ phụ thuộc vào phiên bản của hàm bạn đang cố gắng gọi. Tôi có thể giả định, nhưng rõ ràng tôi không thể chắc chắn một trong hai cách trừ khi bạn nói với tôi. Điều đó sẽ làm việc với trình biên dịch tôi tự hỏi ... –

+0

@KonradRudolph Chữ '0' là một giá trị hợp lệ cho cả' unsigned int' và 'const char *'. –

+0

@RyanP Yeah, tôi thường biết. Không có ý tưởng những gì tôi có nghĩa là trở lại sau đó. –

Trả lời

17

Chữ cái 0 có hai nghĩa trong C++.
Mặt khác, nó là một số nguyên với giá trị 0.
Mặt khác, nó là hằng số rỗng-con trỏ.

Vì chức năng setval của bạn có thể chấp nhận hoặc là int hoặc char*, trình biên dịch không thể quyết định tình trạng quá tải của bạn.

Giải pháp đơn giản nhất là chỉ cần đưa 0 vào đúng loại.
lựa chọn khác là để đảm bảo sự quá tải int được ưa thích, ví dụ bằng cách làm cho một trong những khác mẫu:

class huge 
{ 
private: 
    unsigned char data[BYTES]; 
public: 
    void setval(unsigned int); 
    template <class T> void setval(const T *); // not implemented 
    template <> void setval(const char*); 
}; 
+0

Đối với những gì nó có giá trị, tôi đã phải bao gồm các chuyên ngành bên ngoài tuyên bố lớp học. Về cơ bản bao gồm 'template <> void huge :: setval (const char *);' ngay bên dưới khai báo lớp của bạn. Nếu không, tôi đã nhận được lỗi về việc chuyên mẫu trong phạm vi lớp. Mặc dù vậy, điều này đã làm tôi bối rối trước một số giao diện của tôi. – vmrob

+1

'0' chỉ có một nghĩa trong C++. Nó là một chữ số nguyên của kiểu 'int'. Nếu OP thực sự có quá tải lấy 'int' và một quá trình khác lấy' char * ', độ phân giải quá tải sẽ thành công và chọn quá tải' int'. Tuy nhiên, OP sử dụng 'unsigned int' làm kiểu tham số. Và hai chuyển đổi đó, 'int' ->' unsigned int' vs null pointer constant -> 'char *' là mơ hồ. – dyp

+0

@dyp: Nếu '0' chỉ có một ý nghĩa, làm thế nào nó có thể tham gia vào hai chuyển đổi không rõ ràng với các loại bắt đầu khác nhau? –

1

Sử dụng

p.setval(static_cast<const char *>(0)); 

hoặc

p.setval(static_cast<unsigned int>(0)); 

Như được chỉ ra bởi lỗi, loại 0int. Điều này có thể dễ dàng được truyền tới một số unsigned int hoặc const char *. Bằng cách làm cho các diễn viên bằng tay, bạn đang nói với trình biên dịch mà quá tải bạn muốn.

1

Cast giá trị để trình biên dịch biết hàm nào để gọi:

p.setval(static_cast<const char *>(0)); 

Lưu ý, rằng bạn có một lỗi segmentation trong mã của bạn sau khi bạn nhận được nó để biên dịch (tùy thuộc vào hoạt động bạn thực sự muốn gọi).

3

thay thế p.setval(0); bằng các mục sau.

const unsigned int param = 0; 
p.setval(param); 

Bằng cách đó, nó biết chắc chắn loại 0 là hằng số.

2

Đó là mơ hồ vì một con trỏ chỉ là một địa chỉ, vì vậy một int cũng có thể được coi như một con trỏ - 0 (một int) có thể được chuyển đổi thành int hoặc char unsigned một cách dễ dàng.

Câu trả lời ngắn gọn là gọi p.setval() với một cái gì đó rõ ràng là một trong những loại được triển khai cho: unsigned int hoặc char *. p.setval (0U), p.setval ((unsigned int) 0) và p.setval ((char *) 0) sẽ biên dịch tất cả.

Nói chung, tốt nhất là nên tránh xa tình huống này ngay từ đầu bằng cách không xác định các chức năng quá tải với các loại tương tự như vậy.

+0

+1 cho đoạn cuối nói riêng. –

+0

Không thể đợi C++ 0x, khi chúng ta cuối cùng sẽ có từ khóa nullptr :) –

+0

p.setval ((char *) 0) sẽ biên dịch nhưng ứng dụng bị treo. p.setval (0U) hoạt động tốt – Rajesh

12

Giải pháp này rất đơn giản, nếu chúng ta xem xét các loại giá trị không đổi, mà cần được "unsigned int "thay vì" int ".

Thay vì:

setval(0) 

Sử dụng:

setval(0u) 

Các hậu tố "u" cho trình biên dịch này là một số nguyên unsigned. Sau đó, không cần chuyển đổi và cuộc gọi sẽ rõ ràng.

+1

Câu trả lời hay nhất, đơn giản và thanh lịch để nói với trình biên dịch –

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