Search code examples
c++structgdiimplicit-conversion

C++ implicitly transform trivially constructable struct to member


I feel that its unlikelier than not, but I'd like to see if a function can deduce its parameters from a trivially wrapped struct. For example:

struct wrapped_float
{
  float f;

  wrapped_float(float f) : f(f) {}
};

float saxpy(float a, float x, float y)
{
  return a * x + y;
}

int main()
{
  wrapped_float a = 1.1, x = 2.2, y = 3.3;

  auto result = saxpy(a, x, y); // ofc compile error
}

The motivation behind this is to make a lightweight wrapper around GDI calls with device context handles (HDC). There exists a lot of legacy code which uses HDCs and I'd like to refactor a lot of this code incrementally. My strategy is to make a lightweight wrapper around HDC like this:

#include <Windows.h>

struct graphics
{
  HDC dc;

  graphics(HDC dc) : dc(dc) {}

  void rectangle(int x, int y, int w, int h)
  {
    Rectangle(dc, x, y, x + w, y + h);
  }
};

void OnPaint(HDC dc)
{
  Rectangle(dc, 1, 2, 3, 4);
}

int main()
{
  HDC dc;
  // setup dc here
  graphics g = dc;

  OnPaint(g);
}

So that if g can be implicitly transformed to HDC, then all legacy code will normally compile, but I can slowly refactor code to become like this:

void OnPaint(graphics g)
{
  g.rectangle(1, 2, 3, 4);
}

Any recommendations are also welcome since this simply might not be possible in C++ (or any programming language).


Solution

  • From the comments, I was not aware that C++ had a casting operator. The simple solution is to add:

    struct graphics
    {
      HDC dc;
    
      graphics(HDC dc) : dc(dc) {}
    
      void rectangle(int x, int y, int w, int h)
      {
        Rectangle(dc, x, y, x + w, y + h);
      }
    
      operator HDC()
      {
        return dc;
      }
    };