【问题标题】:How do I use boost::lexical_cast and std::boolalpha? i.e. boost::lexical_cast< bool >("true")如何使用 boost::lexical_cast 和 std::boolalpha?即 boost::lexical_cast< bool >("true")
【发布时间】:2010-12-15 16:13:04
【问题描述】:

我已经看到其他boost::lexical_cast 问题的一些答案断言以下是可能的:

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

这不适用于 g++ 4.4.3 boost 1.43。 (也许它在默认设置std::boolalpha的平台上工作是真的)

This 是字符串转布尔问题的一个很好的解决方案,但它缺少 boost::lexical_cast 提供的输入验证。

【问题讨论】:

  • 关于发布您自己问题的答案的意见参差不齐,但至少将您的答案作为答案发布。
  • 请将您的答案发布为作为答案
  • 已编辑! (由于某种原因,我没有收到您的 cmets 的电子邮件。)

标签: c++ string boost lexical-cast


【解决方案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;
}

【讨论】:

  • BTW- 在operator&gt;&gt;operator&lt;&lt; 接收到的流上使用std::boolalpha 是不是很好?不是按照惯例应该让流保持相同状态的功能吗?
  • 糟糕!为了保持理智,您可以在 iostreams 上使用 boost::ios_flags_saver。
  • 其实我越想。如果您打算在 boost::lexical_cast 之外使用 LocaleBool 的提取/插入运算符,则只需要尊重流的状态。所以在大多数情况下它应该是理智的,但需要注意的是,你不应该将它与用于实际 i/o 的 iostream 混合使用。
  • 真是个天才!!
【解决方案2】:

除了回答表单 poindexter 之外,您还可以将来自 here 的方法包装在 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;
}

我个人喜欢这种方法,因为它隐藏了任何特殊代码(例如,使用链接中的LocaleBoolto_bool(...))来转换为布尔值。

【讨论】:

  • 很简单,但是这个解决方案不应该有if (!ss) throw boost::bad_lexical_cast; 以符合其他专业吗?
【解决方案3】:

将您自己的模板放在 boost 词法转换之上进行解析。请注意示例中的“默认”参数,以确保重载正常工作(如果需要,请随意使用其他方式)。

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

然后,您可以专攻任何东西,包括布尔值:

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

显然有很多方法可以做到这一点,您可以为真与假添加更多条件(我会确保“真”和“假”的所有变体,如“真”,加上“T”和“F”工作正确)。您甚至可以将其扩展到数值解析。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多