Подтвердить что ты не робот

Как использовать boost:: lexical_cast и std:: boolalpha? то есть boost:: lexical_cast <bool> ( "true" )

Я видел несколько ответов на другие вопросы boost::lexical_cast, которые утверждают, что возможно следующее:

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

Это не работает для меня с g++ 4.4.3 boost 1.43. (Возможно, это правда, что он работает на платформе, где по умолчанию установлен std:: boolalpha)

Это является хорошим решением проблемы с строкой для bool, но ей не хватает проверки ввода, которую обеспечивает boost:: lexical_cast.

4b9b3361

Ответ 1

Я отправляю ответ на свой вопрос здесь для других, которые могут искать что-то вроде этого:

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;
    }
};

использование:

#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;
}

Ответ 2

В дополнение к форме ответа poindexter вы можете обернуть метод из здесь в специализированной версии 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();
    }
}

И используйте его:

#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;
}

Мне лично понравился этот подход, потому что он скрывает любой специальный код (например, используя LocaleBool или to_bool(...) из ссылки) для преобразования в/из bools.

Ответ 3

Составьте свой собственный шаблон в дополнение к лексическому приложению boost для синтаксического анализа. Обратите внимание на параметр "default" в этом примере, чтобы обеспечить правильную работу перегрузки (не стесняйтесь использовать другое средство, если хотите).

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

Затем вы можете специализироваться на НИЧЕГО, включая bools:

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

Очевидно, существует несколько способов сделать это, и вы можете добавить дополнительные условия для истинного vs false (я бы удостоверился, что все варианты "TRUE" и "FALSE", такие как "True", плюс "T" и "F" работает правильно). Вы даже можете расширить его до численного разбора.