【问题标题】:Is there a boost lexical_cast equivalent of C# TryParse?是否有与 C# TryParse 等效的 boost lexical_cast?
【发布时间】:2012-11-16 04:00:28
【问题描述】:

简介(来自 Eric Lippert 博客) :

令人烦恼的异常是不幸的设计决策的结果。 令人烦恼的异常以完全非异常的方式抛出 情况,因此必须始终抓住并处理。

令人烦恼的异常的经典示例是 Int32.Parse,它抛出 如果你给它一个不能被解析为整数的字符串。但是 此方法 99% 的用例是转换由 用户,这可能是任何旧事物,因此绝不是 解析失败的例外情况。更糟糕的是,没有办法 来电者提前确定他们的论点是否错误 没有自己实现整个方法,在这种情况下,他们 一开始就不需要调用它。

现在是重要的部分:

这个不幸的设计决定非常令人烦恼,当然 此后不久,框架团队实施了 TryParse 正确的事情。

来自 MSDN Int32.TryParse:

返回值类型:System.Boolean 如果 s 被转换则为真 成功地;否则为假。

所以同事最近正在编写一些需要检查字符串是否为数字的代码,因此在考虑并意识到没有好的 C++ 解决方案之后(基本上它是 for__each/find_if 或 boost:lexical_cast try catch ) 我想拥有is_convertible 或来自 boost 的东西会有多好?

Ofc 我可以包装 boost lexical_cast 并在 try 块结束时返回 true 并在 catch 块结束时返回 false,但我更喜欢现有的做法 :) 解决方案。

【问题讨论】:

  • 顺便说一句,请注意,尽管 Eric 的文章非常引人注目,但它在逻辑上并不连贯:他描述为必要的邪恶(“外生”)的例外实际上并不是必需的 - 只需考虑 IO:C++ IO 流在不使用异常的情况下很好地对这些条件进行建模,Eric 将其描述为必要的。
  • 对不起,我从不关心 iostreams(并且不理解他们得到的仇恨 :D)你说他们有 good(), bad(),... 功能吗?
  • 基本上,是的。默认情况下,它们不是通过异常而是通过标志来指示失败状态,即使是在 .NET 中会引发“外生”异常的状态。
  • idk 老实说,我更喜欢用一种统一的方式在 c++ 中做事,但是我没有足够的返回码/标志/异常的 exp,所以我的意见并不重要。 :)

标签: c# c++ exception boost


【解决方案1】:

如果你可以使用boost,那么你可以使用boost::conversion::try_lexical_convert

#include <boost/lexical_cast/try_lexical_convert.hpp>

std::string str("1.2");
double res;
if(boost::conversion::try_lexical_convert<double>(str, res)){
   //everything normal
}
else{
   //we got a problem
}

【讨论】:

    【解决方案2】:

    >所以同事最近正在编写一些需要检查字符串是否为数字的代码,所以在考虑并意识到没有好的 C++ 解决方案之后

    在 C++11 中,您有 std::stol 和/或 std::stod,它们可以满足您的需求。

    更新 如果您不想使用异常,则strtol(str, &amp;endp) 将进行转换。

    你可以在通话后查看str == endp;如果它们相同,则无法进行转换(因为 endp 将指向字符串未转换部分的开头)

    像这样:

    strtol(str, &endp);
    if (endp==str) { /* no conversion occurred */ }
    

    【讨论】:

    • 嗨,就像我在 QI 中所说的那样,我不喜欢使用 try/catch :“我可以包装 boost lexical_cast 并在 try 块的末尾返回 true 并在 catch 块的末尾返回 false 但是我更喜欢现有的做法 :) 解决方案。” strol 的文档:异常 std::invalid_argument 如果无法执行转换 std::out_of_range 如果转换后的值会超出结果类型的范围。
    • 这样的话,看看std::strtol
    • " 如果无法执行有效转换,则返回零值 (0L)。" , 所以 isNumber = str=="0" || strtol(str);,但是对于 "00","000"... :(
    • 可以查看返回的end_ptr。如果和你传入的指针相同,则说明没有发生转换。
    • strtol(str, &amp;endp ); if (endp==str) {} 没有发生转换。
    【解决方案3】:

    说实话,据我所知没有try_lexical_cast,但你可以做两件事。

    自己是使用流并测试提取是否成功,而不是在大多数情况下lexical_cast 在内部使用流:

     std::string str="56.7";
     std::istringstream ss(str);
     double d;
     if(ss >> d) {
         //passed
     }
     else //failed
    

    当然,正如你提到的,你可以包装lexical_cast

    【讨论】:

      猜你喜欢
      • 2018-09-14
      • 1970-01-01
      • 2021-04-30
      • 2017-01-01
      • 2023-03-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多