Convert any value/type to string callable from C

I'm trying to build a C++ function that converts any type to string.

ex.
int 4 will be "4"
float foo with value of 2.5 will be "2.5"
..
..

So far I'm using a template like this:

1
2
3
4
5
6
7
8
9
10
11
12
#include <string>
#include <sstream>

...
...

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


needs to be use or callable in C.
Last edited on
Something like this, perhaps:

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
#include <string>
#include <sstream>
#include <concepts>

template < typename T > // output_streamable type - an object of type T can be sent to std::ostream
concept output_streamable = requires( std::ostream& stm, const T& v )
{ { stm << v } -> std::same_as<std::ostream&> ; } ;

template < output_streamable T > std::string to_cpp_string( const T& value ) {

	std::ostringstream ss;
	ss << value;
	return ss.str();
}

// returns a pointer to a null-terminated character string owned by the function.
// the string will be overwritten on each invocation of the function. not thread-safe.
template < output_streamable T > const char* to_c_string( const T& value ) {

    static std::string text ;
    text = to_cpp_string(value) ;
    return text.c_str() ;
}

extern "C" // callable from C
{
    // returns a pointer to a null-terminated character string owned by the library.
    // the string will be overwritten on each invocation of the function. not thread-safe.
    const char* as_cstri( int v ) { return to_c_string(v) ; }
    const char* as_cstru( unsigned int v ) { return to_c_string(v) ; }
    const char* as_cstrll( long long v ) { return to_c_string(v) ; }
    const char* as_cstrd( double v ) { return to_c_string(v) ; }
    // etc. for each type we want to support
}
Thanks JLBorges.

I have to mention that I'm trying to make it as a single callable C function.. perhaps using variadic macros (if possible) or detect the type in C and call the right function?

I'm also thinking of adding a callable C function using cpp's typeid..

The user should be put any variable type in C (C99) and will be converted to string.


Last edited on
> detect the type in C and call the right function?

In C11 (not C++), we can use type deduction with the _Generic keyword.
https://en.cppreference.com/w/c/language/generic

1
2
3
4
5
6
7
#ifndef __cplusplus // not C++ 
#define as_cstr(x) _Generic( \
                        int: as_cstri, \
                        unsigned int: as_cstru, \
                        long long: as_cstrll \
                        double: as_cstrd )(x) ;
#endif 
The user should be put any variable type in C (C99) and will be converted to string.

Generic selection is a C11 feature.
https://en.cppreference.com/w/c/language/generic

If you are using GCC and are willing to rely on language extensions you can make do with a combination of __builtin_choose_expr, typeof and __builtin_types_compatible_p.
https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html

Otherwise I don't think there is a mechanism to do this in C99.
Last edited on
Thanks guys for the added info. Yes the C part requires it to be C99.

Solved (for now). mbozzi's language ext. suggestion seem to work compiled with the C99 flag and the compiler supports it.

it seems to be a common extension.. I hope this can be portable.


Last edited on
Topic archived. No new replies allowed.