使用Boost Karma替换STD :: stringstream double到STD :: String Conv



用于改进性能,我希望替换:

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();
}

随着Boost业力的实施,我们的项目已经使用了Boost,并且看起来比上面的幼稚解决方案具有显着的性能增长。

类似:

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;
}

从以下方式采用:http://thisthread.blogspot.com/2011/04/generating-text-with-with-spirit-karma.html似乎在正确的轨道上,但对我来说还不清楚为了控制精度,或者如果可以在不使用类型特征的情况下,对于浮点类型而言,这种解决方案是否可以模板友好。(通过C 14使用的答案是可以接受的。)

您可以借助real_generator的格式策略来实现所需的目标。由于您只需要修改精度,因此您可以从默认的real_policies<Num>派生,然后添加具有您需要行为的precision(Num n)成员函数。

在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:文档(并检查源)似乎暗示成员在这些政策中的功能需要静态,这将使您不可能需要的东西,但是如本示例所示,情况并非如此。p>

最新更新