简体   繁体   English

使用Boost Karma将std :: stringstream替换为double到std :: string的转换

[英]Using Boost Karma to replace std::stringstream for double to std::string Conversion

For performance improvement, I am looking to replace: 为了提高性能,我希望更换:

template<class T> std::string ToStringFixed(const T x, const unsigned int width = 8)
{
  std::stringstream ss;
  ss << std::setprecision(width) << std::fixed << x;
  return ss.str();
}

With an implementation from Boost Karma as our project already uses Boost and it looks to have a significant performance gain over the naive solution above. 通过Boost Karma的实施,我们的项目已经使用了Boost,并且与上述天真的解决方案相比,它似乎具有显着的性能提升。

Something like: 就像是:

std::string ToString(double d)
{
  using boost::spirit::karma::double_;
  using boost::spirit::ascii::space;
  using boost::spirit::karma::generate;

  std::string s
  std::back_insert_iterator<std::string> sink(s);
  generate(sink, double_, d);
  return s;
}

Which is adopted from: http://thisthread.blogspot.com/2011/04/generating-text-with-spirit-karma.html seems to be on the right track, but it isn't clear to me how to control the precision, or if such a solution can be template-friendly for floating point types without use of type traits. 摘自以下网址http : //thisthread.blogspot.com/2011/04/generating-text-with-spirit-karma.html似乎在正确的轨道上,但我尚不清楚如何控制精度,或者这样的解决方案对于浮点类型是模板友好的,而不使用类型特征。 (Answers using up through C++14 are acceptable.) (可以使用通过C ++ 14的答案。)

You can achieve what you want with the help of real_generator 's formatting policies . 您可以借助real_generator的格式化策略来实现所需的功能 Since you only need to modify the precision you can derive from the default real_policies<Num> and then add the precision(Num n) member function that has the behaviour you need. 由于只需要修改精度,因此可以从默认的real_policies<Num>派生,然后添加具有所需行为的precision(Num n)成员函数。

Running on WandBox 在WandBox上运行

#include <iostream>
#include <string>
#include <cmath>

#include <boost/spirit/include/karma.hpp>

template <typename Num>
struct precision_policy : boost::spirit::karma::real_policies<Num>
{
    precision_policy(int prec):precision_(prec){}
    int precision(Num n) const { return precision_; }
    int precision_;
};

std::string ToStringFixedKarma(double d, const unsigned int width = 8)
{
  using boost::spirit::karma::real_generator;
  using boost::spirit::ascii::space;
  using boost::spirit::karma::generate;

  real_generator<double,precision_policy<double> > my_double_(width);

  std::string s;
  std::back_insert_iterator<std::string> sink(s);
  generate(sink, my_double_, d);
  return s;
}

int main() {
    const double pi = std::acos(-1);
    std::cout << ToStringFixedKarma(pi) << std::endl;
    std::cout << ToStringFixedKarma(pi,2) << std::endl;
    std::cout << ToStringFixedKarma(pi,4) << std::endl;
}

PS: The documentation (and inspecting the source) seems to imply that the member functions in these policies need to be static, which would make what you need impossible, but as this example shows, that is not the case. PS:文档(和检查源代码)似乎暗示这些策略中的成员函数必须是静态的,这将使您不需要的内容成为不可能,但是如本示例所示,事实并非如此。

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

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