【问题标题】:Most efficient way to check if object is a String检查对象是否为字符串的最有效方法
【发布时间】:2017-03-29 01:11:17
【问题描述】:

我得到一个对象 (msg.data),它不是数字就是字符串。如果它是一个字符串我不想使用它,如果它是一个我想要的数字。我目前用ostringstream 解决了这个问题,虽然我认为有更好的解决方案:

void scan_cb(const sensor_msgs::LaserScan::ConstPtr& scan)
{
float dist = 0.0f;

std::ostringstream s;
s << scan->ranges[0]; // can be string (always "inf") or a float
if(s.str() != "inf"){
    dist += scan->ranges[0];
}
...

我关心效率,因为这是每秒运行多次的 for 循环的一部分。

基本结构是ROS消息,来自某个主题,基本上可以有任何数据类型。 在这种情况下我使用LaserScan message,文档没有提到range[x] 可以返回“inf”

【问题讨论】:

  • 你的对象总是是一个字符串。您要做的是解析字符串。
  • 如何声明 msg.data?
  • C++ 中没有变体数据类型。如果使用联合或类似方式在类中存储多个数据类型,那么您仍然需要检查数据类型并使用正确的成员
  • 你可能还想忽略NaN(不是数字)。
  • 您能否在 your 源代码中显示声明 msg 的行?

标签: c++ string performance types ros


【解决方案1】:

根据 ROS 文档,scan-&gt;ranges 是一个浮点数组。这是有道理的,因为当ranges[0]字符串表示 不是inf 时,您将它添加到浮点数(dist)。

这意味着(正如 MSalters 在其评论中猜测的那样),您有一个真正的浮点值,并且您只想确保它是一个实数,既不是无限值也不是 NaN(非数字)值。

因此,如果您包含 cmath(或 math.h),您可以使用 C 分类宏来确定数字是有限的(但允许次正规值)还是正常(甚至拒绝次正规值):

void scan_cb(const sensor_msgs::LaserScan::ConstPtr& scan)
{
float dist = 0.0f;

if(isfinite(scan->ranges[0])){
    dist += scan->ranges[0];
}
...

(更多关于wikipedia上浮点数的IEEE-754表示的参考)

【讨论】:

    猜你喜欢
    • 2012-09-03
    • 2011-08-10
    • 2020-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-30
    • 2012-07-13
    相关资源
    最近更新 更多