2014-12-18 18 views
21

Aby użyć operator""s dla std::string, musisz wykonać using namespace std::string_literals. Ale zdefiniowane przez użytkownika literały, które nie zaczynają się od _ są zastrzeżone, więc możliwy konflikt nie może być wymówką. Drugi operator""s pochodzi z std::chrono, ale dotyczy to literałów, więc nie ma tam również konfliktu.Dlaczego operator jest ukryty w przestrzeni nazw?

Jaki jest tego powód?

+0

Och, człowieku ... Pamiętam, że mogłem porozmawiać o tym, CppCon lub Boostcon, ale nie pamiętam, dlaczego tak było. – Borgleader

+0

Chociaż nie znam dokładnego powodu, rozsądne wydaje się unikanie zanieczyszczania globalnej przestrzeni nazw, która jest tak krótkim sufiksem. – Aleph

+1

@Borgleader https://www.youtube.com/watch?v=dTeKf5Oek2c Jest na początku filmu. –

Odpowiedz

19

Istnieją dwa powody, dlaczego właściwie literały są umieszczane w przestrzeni nazw:

  1. uważa się za niepożądane, że użytkownicy będą korzystać using namespace std; tylko zdobyć odpowiednie literałów. Posiadanie literałów zadeklarowanych w specyficznych dla nich przestrzeniach nazw nie powoduje problemu.
  2. W zależności od domeny może być pożądane użycie s jako sufiksu dla czegoś innego. Istnieje już kolejny przyrostek s oznaczający sekundy, ale tak naprawdę nie powodują one konfliktu.

W video of STL's CppCon 2014 talk (wysłane przez remyable w komentarzu) Stephan T. Lavavej wyjaśnia ogólną konstrukcję literały w C++ 14 i jego całkiem jasne, że są one nie miało być w globalnej przestrzeni nazw ! Zamiast tego, dosłowne przyrostki w standardowej bibliotece żyją w hierarchii obszarów nazw inline, dając użytkownikom dokładną kontrolę nad dostępnymi literałami. Na przykład, dosłowne przyrostek ciągów jest zadeklarowana następująco (21,3 [string.classes] pkt 1):

namespace std { 
    inline namespace literals { 
     inline namespace string_literals { 
      string operator"" s(char const* str, size_t len); 
     } 
    } 
} 

Ta hierarchia inline nazw umożliwia użytkownikom uzyskać odpowiedni wybór dosłownych przyrostków:

  • using namespace std; - dostajesz wszystko w standardowej bibliotece C++, włącznie z dosłownymi przyrostkami, bez żadnych kwalifikacji.
  • using namespace std::literals; - otrzymujesz wszystkie dosłowne przyrostki zdefiniowane w standardowej bibliotece C++.
  • using namespace std::string_literals; - otrzymujesz wszystkie dosłowne przyrostki dotyczące łańcuchów.
  • using namespace std::literals::string_literals; - tak, możesz to zrobić, ale naprawdę nie powinieneś: to jest odpowiednik using namespace std::string_literals;.

Oczywiste jest, że komisja nie będzie już do tego wysiłku, gdyby uznać pomysł opłacalne tylko zanieczyszczają globalnej przestrzeni nazw z dosłownych przyrostków, chociaż nie mogą kolidować z dowolnego użytkownika dosłownych przyrostków.

+0

Nie jestem przekonany. Użytkownik niestandardowy kod biblioteki nie może zadeklarować 'operatora '" s "tak czy inaczej? – milleniumbug

+1

@milleniumbug: poprawne: literały zdefiniowane przez użytkownika muszą zaczynać się od '_'.Konflikt nie jest związany z kodem użytkownika, ale z innymi standardowymi klasami bibliotek. Off-hand Nie mogę wymyślić przekonującego przykładu, ale gdy dostaniemy bibliotekę sieciową, może być fajnie stworzyć gniazdo używając "127.0.0.1:80". ... i drugi argument, który nie chce nadawać kodu powodującego zanieczyszczenie 'using namespace std;' trzyma mimo to: o ile mi wiadomo, nie możesz mieć selektywnej "using" -laracji tylko dla operatora dosłownego. –

+1

@milleniumbug Proponowany 'string_view' jest kolejnym potencjalnym kandydatem na literę" "", chociaż w przeszłości używał też '' "sv', aby uniknąć konfliktów. (W obecnym projekcie roboczym nie ma żadnego operatora dosłownego.) Nie wiadomo, które rozwiązanie, jeśli w ogóle, zostanie zachowane (na przykład współbieżne literały "" w różnych przestrzeniach nazw lub w inny sposób). –

Powiązane problemy