C++ format macro / inline ostringstream

前端 未结 7 1336
不知归路
不知归路 2020-12-01 03:18

I\'m trying to write a macro that would allow me to do something like: FORMAT(a << \"b\" << c << d), and the result would be a string -- the s

7条回答
  •  春和景丽
    2020-12-01 03:45

    The problem you are having is related to the fact that operator << (ostream&, char*) is not a member of ostream, and your temporary ostream instance cannot bind to a non-const reference. Instead, it picks the void* overload, which is a member of ostream, and thus doesn't have that restriction.

    The best (but not easiest or most elegant, by any stretch of imagination!) would be to use the Boost Preprocessor to generate a large number of function overloads, each templated on a large number of objects (includes have been omitted and assuming using namespace std;):

    #define MAKE_OUTPUT(z, n, data) \
        BOOST_PP_TUPLE_ELEM(2, 0, data) << BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 1, data), n);
    
    #define MAKE_FORMAT(z, n, data) \
        template  \
        inline string format(BOOST_PP_ENUM_BINARY_PARAMS_Z(z, BOOST_PP_INC(n), T, p)) \
        { \
          ostringstream s; \
          BOOST_PP_REPEAT_##z(z, n, MAKE_OUTPUT, (s, p)); \
          return s.str(); \
        }
    

    It's not guaranteed to work exactly (wrote it without testing), but that's basically the idea. You then call BOOST_PP_REPEAT(N, MAKE_FORMAT, ()) to create a series of functions taking up to N parameters that will format your string as you want to (replace N with the integer of choice. Higher values may negatively affect compile times). This should suffice until you get a compiler with variadic templates. You should read the boost preprocessor documentation, it has very powerful features for things like this. (you can subsequently #undef the macros, after calling the BOOST_PP_REPEAT invocation to generate the functions)

提交回复
热议问题