Search code examples
c++c-preprocessorvariadic-functionsboost-preprocessor

Simple command to combine an arbitrary number of values of arbitrary types into a single string


Consider the following code.

int id = 666;
stringstream stream(stringstream::in | stringstream::out);
stream << "Object " << id << " active.";
file.write(stream.str());

It combines all the values preceded by << in a string quite nicely. I would love to discover a shorter, easier to use version with less code duplication. Furthermore, the above code is just an example, and the command should accept arbitrary combinations of variables and strings. Ideally something like:

int id = 666;
WRITE("Object ", id, " active.");

Is this possible in C++ in a portable way, even with Boost.Preprocessor, inlined functions and all the bag of tricks.


Solution

  • If you really don't want type-checking don't use C++, it's a statically-typed language!

    If you just mean you want it to work for any type, either use a macro (eurgh) or use variadic templates, something like https://gitlab.com/redistd/redistd/blob/master/include/redi/printers.h which supports:

    #include <redi/printers.h>
    using redi::println;
    int main()
    {
      int id = 666;
      println("Object ", id, " active.");  // write arguments to stdout
    }
    

    The println function takes any number of arguments and was shamelessly stolen from inspired by some example code from Howard Hinnant.

    It would be quite easy to adapt that to write to an fstream instead of std::cout e.g. by adding

    inline
    void
    fprintln()
    { file << std::endl; }
    
    template<typename T0, typename... T>
      inline
      void
      fprintln(const T0& t0, const T&... t)
      {
        print_one(file, t0);
        fprintln(t...);
      }
    

    Then:

     fprintln("Object ", id, " active.");  // write arguments to 'file'