简体   繁体   English

是否有相当于 C# TryParse 的 boost lexical_cast?

[英]Is there a boost lexical_cast equivalent of C# TryParse?

Intro (from Eric Lippert Blog) :介绍(来自 Eric Lippert 博客):

Vexing exceptions are the result of unfortunate design decisions.令人烦恼的异常是不幸的设计决策的结果。 Vexing exceptions are thrown in a completely non-exceptional circumstance, and therefore must be caught and handled all the time.恼人的异常是在完全非异常的情况下抛出的,因此必须一直被捕获和处理。

The classic example of a vexing exception is Int32.Parse, which throws if you give it a string that cannot be parsed as an integer.令人烦恼的异常的经典示例是 Int32.Parse,如果给它一个无法解析为整数的字符串,它就会抛出异常。 But the 99% use case for this method is transforming strings input by the user, which could be any old thing, and therefore it is in no way exceptional for the parse to fail.但是此方法的 99% 用例是转换用户输入的字符串,这可能是任何旧事物,因此解析失败绝不是例外。 Worse, there is no way for the caller to determine ahead of time whether their argument is bad without implementing the entire method themselves, in which case they wouldn't need to be calling it in the first place.更糟糕的是,如果不自己实现整个方法,调用者就无法提前确定他们的参数是否错误,在这种情况下,他们不需要首先调用它。

Now the important part:现在重要的部分:

This unfortunate design decision was so vexing that of course the frameworks team implemented TryParse shortly thereafter which does the right thing.这个不幸的设计决定非常令人烦恼,因此框架团队当然在此后不久实施了 TryParse,这做了正确的事情。

From MSDN Int32.TryParse:来自 MSDN Int32.TryParse:

Return Value Type: System.Boolean true if s was converted successfully;返回值 类型:System.Boolean 如果 s 转换成功,则为 true; otherwise, false.否则为假。

So colleague recenly was working on some small bit of code that required checking if a string is a number so after thinking about it and realizing there is no good C++ solution(basically it is a for__each/find_if or boost:lexical_cast try catch) I thought how nice it would be to have is_convertible or something from boost?所以同事最近正在研究一些需要检查字符串是否是数字的小代码,所以在考虑之后并意识到没有好的 C++ 解决方案(基本上它是一个 for__each/find_if 或 boost:lexical_cast try catch)我想拥有is_convertible或 boost 的东西会有多好?

Ofc i can wrap boost lexical_cast and return true at the end of try block and return false at the end of catch block but I prefer existing practice :) solutions. Ofc 我可以包装 boost lexical_cast并在 try 块的末尾返回 true 并在 catch 块的末尾返回 false 但我更喜欢现有的做法 :) 解决方案。

If you can use boost, then you could use boost::conversion::try_lexical_convert :如果您可以使用 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
}

> So colleague recenly was working on some small bit of code that required checking if a string is a number so after thinking about it and realizing there is no good C++ solution > 所以同事最近正在研究一些需要检查字符串是否是数字的小代码,所以在考虑它并意识到没有好的 C++ 解决方案之后

In C++11 you have std::stol and/or std::stod , which may do what you need.在 C++11 中,您有std::stol和/或std::stod ,它们std::stol您的需求。

Update If you don't want to use exceptions, then strtol(str, &endp) will do the conversion.更新如果您不想使用异常,则strtol(str, &endp)将进行转换。

You can check if str == endp after the call;您可以在调用后检查str == endp if they're the same, then no conversion was possible (since endp will point to the beginning of the unconverted portion of the string)如果它们相同,则无法进行转换(因为 endp 将指向字符串未转换部分的开头)

Like this:像这样:

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

Not really, to be honest, as far as I am aware there is no try_lexical_cast but there is two things you can do.不是真的,老实说,据我所知,没有try_lexical_cast但你可以做两件事。

Own is use streams and test that the extraction was successful, not that in most cases lexical_cast uses streams anyway internally:自己是使用流并测试提取是否成功,而不是在大多数情况下lexical_cast在内部无论如何都使用流:

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

Or of course as you mention you can wrap lexical_cast或者当然,正如你提到的,你可以包装lexical_cast

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM