2015-05-15 22 views
6

Vì vậy, hôm nay tôi đã viết một khá khó khăn để tìm lỗi nơi tôi khởi tạo một std :: string để nullptr (không phải là một con trỏ đến std :: string, nhưng giá trị chính nó). Tôi đã tìm thấy rõ ràng nó chỉ có thể làm trong C + + 11 hoặc sau đó với clang.Tại sao bạn có thể gán nullptr cho std :: string?

#include <string> 
#include <iostream> 

using namespace std; 
class Meh{ 
    int x; 
}; 
class Foo 
{ 
private: 
    std::string x=nullptr; 
    Meh y=nullptr; //remove this line and it compiles 
public: 
    std::string z=nullptr; 
}; 

int main(void) 
{ 
    Foo f; 
    cout << f.z; 
    return 0; 
} 

Như bạn có thể thấy, tôi đã thử gán nullptr cho một trường hợp ngẫu nhiên của một lớp và nó không hoạt động. Những gì ma thuật là trong chuỗi cho phép điều này để làm việc, và theo cách nào là cú pháp này thậm chí còn hợp lệ? Tôi cho rằng tôi sẽ gặp lỗi đúc kiểu trong trường hợp này.

Để tham khảo tôi biên soạn với điều này:

clang++ test.cpp -O3 -g -fno-inline -std=c++11 -Wall 

Nó không đưa ra hình thức cảnh báo, mặc dù nó sẽ lôi ra nếu không sử dụng C++ 11

Trả lời

13

Đó là chỉ đơn giản là vì có constructors (số (5) trong liên kết) và assignment operators (số (3) trong liên kết) cho std::string chấp nhận số const char* và do đó các kết quả trùng khớp là nullptr.

Trước C++ 11 (và do đó trước nullptr), cùng một vấn đề xảy ra khi bạn cố gắng xây dựng từ 0 hoặc NULL. Tất cả những trường hợp này là bất hợp pháp và dẫn đến hành vi không xác định, mặc dù ít nhất một STL (RogueWave?) Chấp nhận nó trong quá khứ và tạo ra một chuỗi rỗng.

+6

Đáng chú ý rằng đây là hành vi không xác định ™ – Puppy

+0

Tại sao điều này không hoạt động trước C++ 11? – Earlz

+0

@Earlz 'nullptr' không tồn tại trước C++ 11. – hvd

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