I want to do something like this:
template<int N>
char* foo() {
// return a compile-time string containing N, equivalent to doing
// ostringstream ostr;
// ostr << N;
// return ostr.str().c_str();
}
It seems like the boost MPL library might allow this but I couldn't really figure out how to use it to accomplish this. Is this possible?
First of all, if usually you know the number at run time, you can as easily build the same string. That is, if you have 12
in your program, you can have also "12"
.
Preprocessor macros can add also quotes to arguments, so you can write:
#define STRINGIFICATOR(X) #X
This, whenever you write STRINGIFICATOR(2)
, it will produce "2".
However, it actually can be done without macros (using compile-time metaprogramming). It is not straightforward, so I cannot give the exact code, but I can give you ideas on how to do it:
mpl::string
to build the compile-time string that appends that character.mpl::string
, that has a static value()
string.I took the time to implement it as a personal exercise. Not bad at the end:
#include <iostream>
#include <boost/mpl/string.hpp>
using namespace boost;
// Recursive case
template <bool b, unsigned N>
struct int_to_string2
{
typedef typename mpl::push_back<
typename int_to_string2< N < 10, N/10>::type
, mpl::char_<'0' + N%10>
>::type type;
};
// Base case
template <>
struct int_to_string2<true,0>
{
typedef mpl::string<> type;
};
template <unsigned N>
struct int_to_string
{
typedef typename mpl::c_str<typename int_to_string2< N < 10 , N>::type>::type type;
};
int
main (void)
{
std::cout << int_to_string<1099>::type::value << std::endl;
return 0;
}