2012-10-18 7 views
9

wyniku nie jest możliwe:Dlaczego formatu boost :: nie można konwertować bezpośrednio na std :: string?

std::string s = boost::format("%d") % 1; // error 

Trzeba jawnie wywołać str() metoda:

std::string s = (boost::format("%d") % 1).str(); // OK 

byłoby tylko cukier syntaktyczny, ale dlaczego nie wystarczy dodać konwersję?

+0

Czy przeciążenie% nie wystarczy? :) – jrok

+2

Nie jestem pewien, jakiego rodzaju odpowiedzi szukasz tutaj. Pytasz, czy istnieją jakieś problemy semantyczne, które uniemożliwiają Boostowi realizację czegoś takiego? A może po prostu mówisz: "Powinni byli to zrobić w ten sposób". –

+1

Próbuję zrozumieć zagadnienia semantyczne. Zwykle uważam, że biblioteki boost są dobrze zaprojektowane. –

Odpowiedz

9

Nie jest to bardzo dobra rzecz, jeśli niejawna konwersja może powodować wyjątki. Konwersja na łańcuch domyślnie spowoduje zgłoszenie wyjątku, jeśli mniej argumentów zostanie przesłanych do format niż jest to konieczne. E.g.

std::string f() 
{ 
    boost::format fmt("%d"); 
    // forgot to feed an argument 
    std::string s = fmt; // throws boost::io::too_few_args 
    widget.set_title(fmt); // throws boost::io::too_few_args 
    return fmt; // throws boost::io::too_few_args 
} 

Takie niejawne konwersje utrudniają wykrywanie i analizowanie części kodu, które mogą generować wyjątki. Ale wyraźne wywołania .str() dają wskazówkę dotyczącą takich możliwych wyjątków, co ułatwia życie, zapewniając wyjątkowe bezpieczeństwo kodu otaczającego, a także (w tym konkretnym przypadku) podpowiedź do podwójnego sprawdzenia poprzedniego kodu, aby zapobiec powstaniu wyjątku. .

+0

Obie odpowiedzi (ta i ta z BigBoss) dają dobre powody dla nie mając niejawnej konwersji. Ale musiałem zaakceptować tylko jedną :-) –

+0

@mr_georg Dzięki :) – usta

10

Myślę, że powodem tego jest taka sama jak std::stringstream w tym kontekście należy również używać .str() przekształcić strumień do sznurka i takie same dla boost::formatter a powodem jest jako:

std::string s1 = "Hello ", s2 = "World"; 
format("%s.") % s1 + s2; 

Teraz jeśli boost::formatter było niejawnie wymienialne na std::string, a następnie tworzy "Hello .World", ponieważ format("%s.") % s1 zostanie przekonwertowane na "Hello". a następnie zostanie domyślnie przekonwertowany na std::string i użyje operator+, aby dodać go do s2, ale prawdopodobnie większość programistów chce mieć "Hello World". a to będzie źródłem błędu i zamieszania. Jednak w przypadku, gdy nie niejawna konwersja istnieje kompilator wygeneruje błąd za to (bo nie ma operator+ dla boost::formatter i std::string) i aby go naprawić albo jako format("%s.") % (s1 + s2) lub str(format("%s.") % s1) + s2