逐字字符串化

时间:2015-09-16 09:57:54

标签: c++

是否可以调整常见的C ++字符串化方法:

template<typename T> 
std::string Stringify(T const &value) 
{
    std::stringstream ss;
    ss << value;
    return ss.str();
}

以便打印实际值,而不是值的截断或科学记数法表示,例如:

std::cout << Stringify(std::numeric_limits<float>::max()) << std::endl;

不应该打印3.40282e+38而是3'402'82...(我只是不提及其他数字,我并不是说应该打印点数)

2 个答案:

答案 0 :(得分:4)

是的,将您想要的操纵器添加到功能签名中并将它们转发到流中。

template<typename T, typename Manip> 
std::string Stringify(T const &value, Manip manip) 
{
    std::stringstream ss;
    ss << manip << value;
    return ss.str();
}

使用示例代码;

int main()
{
    using namespace std;
    // The precision here is set to be sufficient to print the test platform
    cout << Stringify(numeric_limits<float>::max(), setprecision(50)) << endl;
}    

我假设将使用多个操纵器。为此,可以为所需数量的操纵器添加函数重载,或者可以使用(使用C ++ 11)可变参数模板并完美转发。

template <typename Stream>
Stream& AddManip(Stream& str)
{
    // end the recursion
    return str;
}

template <typename Stream, typename Head, typename... Tails>
Stream& AddManip(Stream& str, Head&& head, Tails&&... tails)
{
    // add the head manipulator and forward the rest
    str << std::forward<Head>(head);
    return AddManip(str, std::forward<Tails>(tails)...);
}

template<typename T, typename... Manip> 
std::string Stringify(T const &value, Manip&&... manip) 
{
    std::stringstream ss;
    // add the manipulators to the stream
    AddManip(ss, std::forward<Manip>(manip)...);
    ss << value;
    return ss.str();
}

int main()
{
    using namespace std;
    cout << Stringify(numeric_limits<int>::max(), setprecision(40), std::hex) << endl;
}    

答案 1 :(得分:1)

我知道宏是邪恶的,但我的作品中有一两个例外。其中一个是this macro

#include <sstream>

#define SSTR( x ) static_cast< std::ostringstream & >( \
        ( std::ostringstream() << std::dec << x ) ).str()

Detailed explanation available

这种结构的一个优点是操纵器可以很容易地内联:

 std::string str = SSTR( "numeric_limits<float>::max is: "
                       << setprecision(50)
                       << numeric_limits<float>::max()
                       );

另一个优点是它紧凑,而且非常C ++ 98。

缺点是它是一个宏。 ; - )