Multiple data streams in one class, handling all in one member

I have to implemente the to_string method. Whats the fastest way? Stringstreams. But I have to use C++ without any headers help, so I need to implement the stringstream class. How can an stringstream hold one float? An double? Hoq cqn I implement an strigstream myself?
iQChange wrote:
But I have to use C++ without any headers help,
Who imposes this ludicrous restriction upon you? That's like saying "build this car without using any toolboxes".

Stringstreams don't store the original data types, the serialize them to string form and concatenate them to an internal buffer. The buffer is length terminated, not null terminated, just like a std::string.
Last edited on
I have an string that I made. I can use it ;)
Whats the fastest way? Stringstreams.


What gave you that idea? Stringstreams perform a lot of extra data allocations, so if you want something speedy, use snprintf. In C (and maybe some C++ compilers) <stdio.h> is included automatically, so it doesn't matter about your 'no header' rule. Also, seriously, there is no point to you doing this: The string classes made for your compiler are created by a bunch of very knowledgeable people who know a lot about the compiler: It will always be better than yours.

EDIT:
I'm not saying that you should use snprintf, it has a lot of disadvantages to string streams. Its just that it happens to faster, and I was just refuting your claim that stringstreams are faster. It normally doesn't matter though (unless your profiler tells you it does).
Last edited on
AND snprintf is unsafe. I really need to implement stringstreams. Understand my question as "How cast mutiple types of data to a stream?"...
I can understand the problem with sprintf, but why is snprintf unsafe?
> I can understand the problem with sprintf, but why is snprintf unsafe?

Both are equally type-unsafe.

Other than that, there is nothing inherently unsafe with either sprintf() or snprintf()
Last edited on
Any idea?
> handling all in one member

Write a bunch of overloads; one per supported type.
And then dispach to the appropriate overload from within the one template member.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <iostream>
#include <cstdio>

namespace detail_
{
    char* to_string( int v, char* cstr, std::size_t n )
    { return std::snprintf( cstr, n, "%d", v ) > 0 ? cstr : nullptr ; }

    template < std::size_t N > char* to_string( int v, char (&array)[N] )
    { return to_string( v, array, N ) ; }

    char* to_string( double v, char* cstr, std::size_t n )
    { return std::snprintf( cstr, n, "%f", v ) > 0 ? cstr : nullptr ; }

    template < std::size_t N > char* to_string( double v, char (&array)[N] )
    { return to_string( v, array, N ) ; }

    // etc ...
    // one overload per supported type
}

struct my_struct
{
    template < typename T >
    static char* to_string( T&& v, char* cstr, std::size_t n )
    { return detail_::to_string( v, cstr, n ) ; }

    template < typename T, std::size_t N >
    static char* to_string( T&& v, char (&array)[N] )
    { return detail_::to_string( v, array ) ; }
};

int main()
{
    char cstr[100] ;
    std::cout << my_struct::to_string( 1234, cstr ) << '\n' ;
    std::cout << my_struct::to_string( 12.34, cstr ) << '\n' ;
}

http://coliru.stacked-crooked.com/a/8ca5c8e6b3d08802
Topic archived. No new replies allowed.