2011-10-21 33 views
6

Tôi đã C++ mã sau:Cast trong nhà xây dựng cho loại C++

#include <iostream> 
#include <string> 

    int main(int argc, char* argv[]) 
    { 
     const std::string s1 = "ddd"; 
     std::string s2(std::string(s1)); 
     std::cout << s2 << std::endl; 
    } 

Kết quả là: Tại sao? Khi tôi sử dụng Wall cờ, trình biên dịch ghi cảnh báo: địa chỉ của 'std :: string s2 (std :: string)' sẽ luôn luôn đánh giá là 'true'

Nhưng mã này:

#include <iostream> 
#include <string> 

int main(int argc, char* argv[]) 
{ 
    const std::string s1 = "ddd"; 
    std::string s2((std::string)(s1)); 
    std::cout << s2 << std::endl; 
} 

kết quả: ddd

Đó là bình thường kết quả

+3

Không thể bạn chỉ cần thực hiện dòng thứ hai 'std :: string s2 (s1); 'Tại sao bạn cần phải bao gồm 'std :: string' thứ hai? – rhololkeolke

+1

Tại sao tạo bản sao trung gian? Tại sao không 'std :: string s2 = s1;'? –

+0

@Oscar: Phiên bản của bạn tạo biến khởi tạo mặc định trung gian và sau đó sao chép thông qua toán tử gán bản sao. Phiên bản chính xác mà không có bất cứ điều gì trung gian là rho. – Xeo

Trả lời

13

Most-vexing-parse.

std::string s2(std::string(s1)); 

được phân tách như tuyên bố của một "chức năng tham gia một tham số std::string tên s1 và trả về một std::string". Sau đó, bạn cố gắng in hàm đó, đầu tiên sẽ chuyển đổi nó thành một con trỏ hàm (quy tắc phân rã/chuyển đổi thông thường). Vì operator<< của std::ostream không bị quá tải đối với các con trỏ hàm, nó sẽ thử chuyển đổi thành bool, thành công và vì con trỏ hàm không rỗng, nó được chuyển thành giá trị boolean true, được in dưới dạng 1.

Thay đổi nó để

std::string s2((std::string(s1))); 

hoặc thậm chí tốt hơn, chỉ

std::string s2(s1); 
+0

Hoặc 'std :: string s2 = s1;' –

+1

@Oscar: Sao chép ctor> toán tử gán bản sao. :) – Xeo

+7

'std :: string s2 = s1;' gọi hàm tạo bản sao vì nó là khai báo. –

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