2017-02-15 1 views
2

のためのstd ::にstringstreamを置き換えるためにカルマブーストを使用して、私は交換する探しています:性能向上のために、二重はstdする::文字列変換

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

をブーストカルマからの実装では、私たちのプロジェクトは、すでにブーストを使用してし、上記の単純なソリューションよりも大幅なパフォーマンス向上が見られます。採用されている

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は正しい軌道に乗ってのようですが、精度を制御する方法を私に明確ではない、またはそのような解決策は、テンプレートできる場合型特性を使用しない浮動小数点型には親しみやすい。 (C++ 14を使って回答することもできます)

+0

@NeilButterworth私の知る限りでは、std :: to_stringはフォーマットの制御を許可していません。ここで私は精度をコントロールしたいと思っています。他の機能では、出力の幅を制御することもできます。 Std :: stringstreamではこれがすべて簡単ですが、よりパフォーマンス重視のソリューションが必要です。 – DiB

答えて

5

real_generator's formatting policiesの助けを借りて、あなたは何を望むことができますか?精度を変更する必要があるのは、デフォルトのreal_policies<Num>から派生してから、必要な動作を持つprecision(Num n)メンバ関数を追加するだけです。

Running on 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:ドキュメント(とソースを検査するには)あなたが不可能に必要なものを作ることになる、これらのポリシーでのメンバ関数は静的である必要があることを意味するものではなく、this exampleが示すように思わ、そうではありません。

関連する問題