Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Verbatim stringify

Tags:

c++

Is it possible to tweak the common C++ stringification method :

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

so that the actual value will be printed and not a truncation or scientific notation representation of the value, eg :

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

should not print 3.40282e+38 but 3'402'82... (I'm just not mentioning the rest of the digits, I'm not implying that dots should be printed)

like image 963
Nikos Athanasiou Avatar asked May 27 '26 09:05

Nikos Athanasiou


1 Answers

Yes, add the manipulator(s) you desire to the function signature and forward them to the stream.

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

With the sample code;

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

I assume that more than one manipulator will be used. To this end, function overloads can be added for the desired number of manipulators, or you can use (with C++11) variadic templates and perfect forwarding.

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;
}    
like image 51
Niall Avatar answered May 31 '26 10:05

Niall



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!