2016-03-03 11 views
18

Deklaracja C++ ciąg is the following:Czy jest jakiś użytek z basic_string <T> gdzie T nie jest typem znaku?

template< 
    class CharT, 
    class Traits = std::char_traits<CharT>, 
    class Allocator = std::allocator<CharT> 
> class basic_string; 

CharT jest typ charakteru, który może być char, wchar_t, char16_t i char32_t; ale po wszystkim basic_string jest szablonem, więc można go utworzyć z innymi CharT i innymi podzielnikami. Choć może myślę, że w niektórych przypadkach użycie do innych podzielników nie jestem w stanie myśleć w przypadkach użycia ciągów innych typów danych, na przykład:

using string = std::basic_string<int>; 

używając ciąg liczb całkowitych, nie możemy zainicjować go jako ciąg (oczywiste) ani struny u32 (nie takie oczywiste, przynajmniej dla mnie); ale możemy go zainicjować z initializer_list dopóki zawarte typ listy jest zamienny do int:

string err1("test"); // Error! 
string err2(U"test"); // Error! 
string err3{"test"}; // Error! 
string err4{U"test"}; // Error! 
string err5 = "test"; // Error! 
string err6 = U"test"; // Error! 

string success1({U't', U'e', U's', U't'}); 
string success2 = {U't', U'e', U's', U't'}; 
string success3({'t', 'e', 's', 't'}); 
string success4 = {'t', 'e', 's', 't'}; 

Ale nawet jeśli uda nam się zainicjować ciąg liczb całkowitych, nie możemy używać go w normalny sposób:

std::cout << success1; // Error! expected 116101115116 

jedyny basic_string oczekiwanego być używany z coutnormalne te, które ma sens: w końcu nie możemy zakładać, jaki ma być wydrukowany ciąg liczb całkowitych lub ciąg MyFancyClass es.

Ale w każdym razie tworzenie instancji dziwnych instancji basic_string nie jest zabronione; z jednej strony nie jest zabronione ze względu na brak cech, które zabraniają takiego używania (aka koncepcje) i na innym kodowaniu jest łatwiejsze niż robienie tego w przeciwny sposób (bez pojęć), więc to mnie zastanawia. :

  • Czy jest jakiś pożytek z std::basic_string<T>, gdzie T nie jest typem znaku?

chodzi o Jakiekolwiek użycie myślę o rzeczach, które można osiągnąć tylko z ciągów T i które nie mogą być wykonane z wektorem T (czy będzie to znacznie trudniejsze do zrobienia), innymi słowy :

  • Czy zdarzyło Ci się kiedyś, że lepszy wybór to ciąg T?
+0

Czy możesz wymyślić coś, co string może zrobić lepiej niż wektor? – NathanOliver

+0

@NathanOliver Printing? – BoBTFish

+0

Czy nie jest to prawie to samo pytanie co "Co możesz zrobić z' std :: basic_string ', którego nie możesz zrobić z' std :: vector '?" – user463035818

Odpowiedz

2

Podczas budowania tokenizera, char [n] lub enum przychodzi na myśl. Zwróć uwagę, że konstruktor Token nie jest uruchamiany przez basic_string.

#include <iostream> 
#include <string> 
#include <string.h> 

static const int max_token_length = 10; 

struct Token 
{ 
    char str[max_token_length]; 
}; 

// define std::char_traits<Token> if your implementation defaults are not fine for you (or don't exist as it's not required) 

int main() { 
    Token t; 
    strncpy(t.str, "for", max_token_length); 
    std::basic_string<Token> s1(1, t); 

    Token u; 
    strncpy(t.str, "for", max_token_length); 
    std::basic_string<Token> s2(1, u); 

    std::basic_string<Token> s = s1 + s2; 

    return 0; 
} 
+2

co masz na myśli przez "konstruktor nie jest uruchamiany"? Oczywiście, że jest! Prawo w tej linii: 'std :: basic_string s;', domyślny konstruktor. Nawiasem mówiąc, [zgodnie z moją pamięcią i tą stroną] (http://en.cppreference.com/w/cpp/string/basic_string/basic_string) konstruktor domyślny basic_string inicjuje go jako puste wystąpienie (łańcuch o długości zero, ** nieokreślona pojemność **). Oznacza to, że s [0] ** może ** jeszcze nie istnieć, dopóki nie ustawisz go poprawnie. – quetzalcoatl

+0

Jednak poza tym przykładem "tokenizera" jest dobra odpowiedź na to pytanie. Możesz teraz wykonywać łańcuchy znaków (concatenate/substring/etc) na łańcuchach-tokenów ... ale czy bardziej przydatne są inne kontenery? Właściwie wątpię. – quetzalcoatl

+1

@quetzalcoatl: Konstruktor tokena nie jest uruchamiany (wykonywane jest tylko przydział), oczywiście wykonywany jest konstruktor basic_string . Edytowanie w celu wyjaśnienia tego. Możesz to sprawdzić: jeśli dodasz typ, w którym przypisanie jest nieprawidłowe przed konstruktorem, zwykle kończy się niepowodzeniem. Jest to (jeden z powodów), dlaczego nie możemy mieć std :: basic_string >. – lorro

1

Jeśli masz do czynienia z systemem, który obsługuje wiele kodowanie tekstowe (np ASCII i EBCDIC), może chcesz oddzielny typ charakteru i typu string dla każdego kodowania. Powinny być traktowane jako struny, ale są wyraźnie odrębnymi typami.

Powiązane problemy