使用 Boost Karma 替换 std::stringstream 以进行 double 到 std::string 的转换
Using Boost Karma to replace std::stringstream for double to std::string Conversion
为了提高性能,我正在寻找替换:
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 Karma 的实现,因为我们的项目已经使用了 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-spirit-karma.html 似乎是在正确的轨道上,但我不清楚如何控制精度,或者这样的解决方案是否可以对浮点模板友好不使用类型特征的类型。 (可以接受使用 up 到 C++14 的答案。)
你可以在real_generator
's formatting policies的帮助下实现你想要的。由于您只需要修改可以从默认 real_policies<Num>
派生的精度,然后添加具有您需要的行为的 precision(Num n)
成员函数。
#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:文档(和检查源代码)似乎暗示这些策略中的成员函数需要是静态的,这将使您无法实现所需,但正如 this example 所示,事实并非如此。
为了提高性能,我正在寻找替换:
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 Karma 的实现,因为我们的项目已经使用了 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-spirit-karma.html 似乎是在正确的轨道上,但我不清楚如何控制精度,或者这样的解决方案是否可以对浮点模板友好不使用类型特征的类型。 (可以接受使用 up 到 C++14 的答案。)
你可以在real_generator
's formatting policies的帮助下实现你想要的。由于您只需要修改可以从默认 real_policies<Num>
派生的精度,然后添加具有您需要的行为的 precision(Num n)
成员函数。
#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:文档(和检查源代码)似乎暗示这些策略中的成员函数需要是静态的,这将使您无法实现所需,但正如 this example 所示,事实并非如此。