2015-05-15 11 views
6

Więc dzisiaj napisałem dość trudny do znalezienia błąd, w którym zainicjowałem std :: string na nullptr (nie wskaźnik na std :: string, ale sama wartość). Odkryłem, że jest to możliwe tylko w C++ 11 lub później z klangiem.Dlaczego można przypisać nullptr do 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; 
} 

Jak widać, próbowałem przydzielić nullptr tylko przypadkowemu wystąpieniu klasy i nie zadziałało. Jaka jest magia w łańcuchu, która pozwala na to, aby działała, iw jaki sposób jest to nawet poprawna składnia? Zakładałem, że w tym przypadku napotkam błąd typu casting.

Dla odniesienia I skompilowany z tego:

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

To nie dał formę ostrzeżenia, chociaż byłoby błędu, jeśli nie przy użyciu C++ 11

Odpowiedz

13

To po prostu dlatego, że są constructors (numer (5) w łączu) i assignment operators (numer (3) w łączu) dla std::string, które akceptują const char*, a zatem dopasowują nullptr.

Przed C++ 11 (a więc przed nullptr), ten sam problem wystąpił podczas próby skonstruowania od 0 lub NULL. Wszystkie te przypadki były nielegalne i skutkowały niezdefiniowanym zachowaniem, chociaż przynajmniej jeden STL (RogueWave?) Zaakceptował go w przeszłości i wygenerował pusty ciąg.

+6

Warto zauważyć, że jest to niezdefiniowane zachowanie ™ – Puppy

+0

Dlaczego to nie zadziałało przed C++ 11? – Earlz

+0

@Ellz 'nullptr' nie istniał przed C++ 11. – hvd