2017-02-15 11 views
2

에 대한 표준 : 이제 stringstream을 대체 할 카르마 부스트를 사용하여, 나는 교체 찾고 있어요 :성능 향상을 위해 이중 성병 : : 문자열 변환

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 쇼로, 그것은 사실이 아닙니다.