TonyK
TonyK

Reputation: 13

Store snprintf arguments for later use

I want my GUI application to print dynamic data on the screen (mouse coords etc.) through a user-defined format and using user-choosed variables. I need something like a class that stores this format (a char*) and all its variables pointers (int*, char*, std::string* etc.)

Let's say I want a tooltip balloon to display mouse coordinates. My class would be:

class Printer{
private:
char *format;
// std::vector with pointers? Variadic template?

public:
   Printer(char *format, ...){
      // code
   }
};

User would define a format with variables:

int x, y;
Printer p("X (%d), Y (%d)", &x, &y);

The mouse callback function would update x and y values. And Printer would do:

snprintf(buffer, sizeof(buffer), format, *variables);

After that, buffer contains the updated values of x and y, and one could simply pass it to the tooltip.

How can I achieve this?

Upvotes: 1

Views: 427

Answers (1)

max66
max66

Reputation: 66240

I don't know if is possible, with a variadic list of arguments, pre C++11.

But starting from C++11, using variadic templates (to pass the variadic list of arguments to the constructor) and a lambda function (where you can capture the variadic list of references of arguments), you can write something as

class Printer
 {
   private:
      char                              buffer[1024];
      std::string                       format;
      std::function<std::string(void)>  l;

   public:
      template <typename ... Args>
      Printer (char const * f0, Args & ... as) : format{f0}
       {
         l = [&] () -> std::string
          {
            snprintf(buffer, sizeof(buffer)/sizeof(buffer[0]),
                     format.c_str(), as...);

            return buffer;
          };
       }

      std::string callback () const
       { return l(); }
 };

You can use Printer as follows

int main ()
 {
   int x{10}, y{20};

   Printer p{"X (%d), Y (%d)", x, y};

   x = 100;
   y = 200;

   std::cout << p.callback() << std::endl; // print X (100), Y (200)
 }

Observe that x and y are passed as references, not as pointers.

Upvotes: 1

Related Questions