2010-12-15 19 views
17

Widziałem kilka odpowiedzi na pytania, które innych boost::lexical_cast dochodzić po to możliwe:Jak korzystać z boost :: lexical_cast i std :: boolalpha? tj boost :: lexical_cast < bool > ("true")

bool b = boost::lexical_cast<bool>("true"); 

To nie działa na mnie z g ++ 4.4.3 Boost 1.43. (Może to prawda, że ​​działa na platformie, na której domyślnie ustawiono std :: boolalpha)

This to dobre rozwiązanie problemu z ciągiem znaków, ale brakuje w nim sprawdzania poprawności danych, które zwiększa :: lexical_cast.

+4

Opinie na temat zamieszczania odpowiedzi na własne pytania są mieszane, ale przynajmniej umieść odpowiedź jako odpowiedź. – robert

+3

Proszę zaksięgować odpowiedź ** jako odpowiedź **. –

+0

edytowane! (z jakiegoś powodu nie otrzymałem e-maila z Twoimi komentarzami.) – poindexter

Odpowiedz

15

jestem delegowania odpowiedzi na moje własne pytanie tutaj dla innych, którzy mogą być patrząc na coś takiego:

struct LocaleBool { 
    bool data; 
    LocaleBool() {} 
    LocaleBool(bool data) : data(data) {} 
    operator bool() const { return data; } 
    friend std::ostream & operator << (std::ostream &out, LocaleBool b) { 
     out << std::boolalpha << b.data; 
     return out; 
    } 
    friend std::istream & operator >> (std::istream &in, LocaleBool &b) { 
     in >> std::boolalpha >> b.data; 
     return in; 
    } 
}; 

Wykorzystanie:

#include <boost/lexical_cast.hpp> 
#include <iostream> 
#include "LocaleBool.hpp" 

int main() { 
    bool b = boost::lexical_cast<LocaleBool>("true"); 
    std::cout << std::boolalpha << b << std::endl; 
    std::string txt = boost::lexical_cast<std::string>(LocaleBool(b)); 
    std::cout << txt << std::endl; 
    return 0; 
} 
+0

BTW- czy dobrze jest używać 'std :: boolalpha' w strumieniu odbieranym w' operator >> 'lub' operator << '? Czy funkcja nie ma na celu pozostawienia strumienia w tym samym stanie? – Kos

+1

Ups! Aby zachować zdrowie psychiczne, możesz użyć boost :: ios_flags_saver na Iostreams. – poindexter

+0

W rzeczywistości im więcej o tym myślę. Chcielibyśmy uszanować stan strumieni, jeśli zamierzasz używać operatorów pobierania/wstawiania LocaleBool poza boost :: lexical_cast. W większości przypadków powinno to być przy zdrowych zmysłach, z zastrzeżeniem, że nie należy mieszać go z używanym systemem iostream do rzeczywistego wejścia/wyjścia. – poindexter

10

Oprócz Poindexter formularza odpowiedzi, można zawijać metodę z here w wyspecjalizowanej wersji boost::lexical_cast:

namespace boost { 
    template<> 
    bool lexical_cast<bool, std::string>(const std::string& arg) { 
     std::istringstream ss(arg); 
     bool b; 
     ss >> std::boolalpha >> b; 
     return b; 
    } 

    template<> 
    std::string lexical_cast<std::string, bool>(const bool& b) { 
     std::ostringstream ss; 
     ss << std::boolalpha << b; 
     return ss.str(); 
    } 
} 

i używać go:

#include <iostream> 
#include <boost/lexical_cast.hpp> 

//... specializations 

int main() { 
    bool b = boost::lexical_cast<bool>(std::string("true")); 
    std::cout << std::boolalpha << b << std::endl; 
    std::string txt = boost::lexical_cast<std::string>(b); 
    std::cout << txt << std::endl; 

    return 0; 
} 

Osobiście lubiłem tego podejścia, ponieważ ukrywa żadnego specjalnego kodu (np przy użyciu LocaleBool lub to_bool(...) z łącza) do konwersji do/z sygnałów.

0

Skonfiguruj własny szablon, aby zwiększyć liczbę leksykalnych rzutów do parsowania. Zwróć uwagę na parametr "domyślny" w przykładzie, aby upewnić się, że przeciążenie działa poprawnie (jeśli chcesz, możesz użyć innych środków).

template<typename T> 
T Parse(const std::string& valStr, const T& default=T()) { 
    T result = boost::lexical_cast<T>(valStr); 
} 

Następnie można specjalizować się na wszystko, w tym bools:

template<> 
bool Parse(const std::string& valStr, const bool& default=true) { 
    if(strcmp(valStr.c_str(), "true") == 0) { 
     return true; 
    } 
    return false; 
} 

Oczywiście istnieje wiele sposobów, aby to zrobić, i można dodać więcej warunków dla prawdą vs false (ja upewnij się, że wszystkie warianty "TRUE" i "FALSE", jak "True", plus "T" i "F" działają poprawnie). Można nawet rozszerzyć go na parsowanie numeryczne.