2009-07-19 31 views
14

Với phương pháp sau đây:Tại sao chuỗi được trích dẫn khớp với chữ ký phương thức bool trước chuỗi std ::?

// Method 1 
void add(const std::string& header, bool replace); 

//Method 2 
void add(const std::string& name, const std::string& value); 

Nó sẽ xuất hiện đoạn mã sau sẽ kết thúc phương pháp 1 kêu gọi thay vì phương pháp 2:

something.add("Hello", "World"); 

tôi đã kết thúc việc tạo ra một phương pháp mà trông như thế này:

//Method 3 
void MyClass::add(const char* name, const char* value) { 
    add(std::string(name), std::string(value)); 
} 

Nó hoạt động. Vì vậy, nó sẽ có vẻ rằng khi một phương pháp chấp nhận một "chuỗi trích dẫn" nó sẽ phù hợp theo trình tự sau:

  1. const char*
  2. bool
  3. std::string

Tại sao một chuỗi trích dẫn sẽ được đối xử dưới dạng bool trước một số std::string? Đây có phải là hành vi thông thường không? Tôi đã viết một số tiền phong nha của mã cho dự án này và chưa có bất kỳ vấn đề nào khác với chữ ký sai phương thức được chọn ...

Trả lời

14

Đoán của tôi là chuyển đổi từ con trỏ sang bool là một chuyển đổi kiểu nguyên thủy ngầm, chuyển đổi thành std::string yêu cầu cuộc gọi của người xây dựng và xây dựng tạm thời.

+2

Đây là nó. Tôi đã có vấn đề này một lần và nó nhầm lẫn tôi, nhưng tham số thứ hai của bạn là một const char *, và điều đó sẽ được chuyển đổi thành một boolean. – GManNickG

6

Con trỏ có chuyển đổi ẩn thành bool. Có lẽ bạn đã thấy những điều sau đây:

void myFunc(int* a) 
{ 
    if (a) 
     ++(*a); 
} 

Bây giờ, trong C++, chuyển đổi ngầm giữa built-in loại được ưu tiên hơn chuyển đổi giữa đẳng cấp loại. Vì vậy, ví dụ, nếu bạn đã có một lớp:

class Int 
{ 
public: 
    Int(int i) {} 
} 

Và bạn quá tải một chức năng cho longInt:

void test(long n) {cout << "long";} 
void test(Int n) {cout << "Int";} 

Bạn sẽ thấy rằng đoạn mã sau gọi là tình trạng quá tải dài:

int i; 
test(i); 
+0

Lưu ý rằng std :: string là "do người dùng định nghĩa", mặc dù được định nghĩa theo tiêu chuẩn. Tôi nghĩ rằng thuật ngữ thích hợp hơn là "loại lớp" so với "loại không phải lớp". – MSalters

+0

Điểm tốt. Đã chỉnh sửa. – rlbond

9

Trong trường hợp của bạn, bạn đã có các chức năng quá tải. Quá tải độ phân giải xảy ra theo Mục 13.3.

C++ 03 13.3.3.2/2:

Khi so sánh các hình thức cơ bản của trình tự chuyển đổi ngầm (theo quy định tại 13.3.3.1)
- chuỗi chuyển đổi tiêu chuẩn (13.3.3.1 .1) là chuỗi chuyển đổi tốt hơn chuỗi chuyển đổi do người dùng xác định hoặc chuỗi chuyển đổi dấu ba chấm và
- chuỗi chuyển đổi do người dùng xác định (13.3.3.1.2) là chuỗi chuyển đổi tốt hơn chuỗi chuyển đổi dấu ba chấm (13.3 .3.1.3).

Con trỏ chuyển đổi thành bool là chuyển đổi chuẩn. Con trỏ chuyển đổi thành std :: string là một chuyển đổi do người dùng xác định.

4,12 chuyển đổi Boolean Một rvalue của số học, điều tra, con trỏ, hoặc con trỏ đến loại thành viên có thể được chuyển đổi sang một rvalue loại bool. Một giá trị bằng không, giá trị con trỏ null, hoặc giá trị con trỏ thành viên null được chuyển thành false; bất kỳ giá trị nào khác được chuyển thành true.

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