是否可以调整常见的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...
(我只是不提及其他数字,我并不是说应该打印点数)
答案 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。
缺点是它是一个宏。 ; - )