【问题标题】:C++ implicitly transform trivially constructable struct to memberC ++隐式将可构造的结构隐式转换为成员
【发布时间】:2019-01-25 08:27:28
【问题描述】:

我觉得这不太可能,但我想看看一个函数是否可以从一个简单包装的结构中推断出它的参数。例如:

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
}

这样做的动机是使用设备上下文句柄 (HDC) 围绕 GDI 调用创建一个轻量级包装器。存在很多使用 HDC 的遗留代码,我想逐步重构很多这些代码。我的策略是像这样围绕 HDC 制作一个轻量级包装器:

#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);
}

这样如果g可以隐式转换为HDC,那么所有遗留代码都会正常编译,但我可以慢慢重构代码变成这样:

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

也欢迎任何建议,因为这在 C++(或任何编程语言)中可能根本不可能。

【问题讨论】:

  • 为什么在这里简单地实现明显的operator float 不够?
  • 其实我不知道这是可能的。它确实足够了。谢谢。

标签: c++ struct gdi implicit-conversion


【解决方案1】:

在 cmets 中,我不知道 C++ 有一个强制转换运算符。简单的解决方案是添加:

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;
  }
};

【讨论】:

  • 根据HDC 类型,您可能会使用const ref,并可能标记或添加方法const: operator const HDC&amp;() const
  • @Jarod42 与句柄副本相比,返回 const 引用有什么好处?不过,我会将函数设为 const
  • 返回引用避免了复制对象的开销。 const 引用确保无法修改对象。
  • @SamVarshavchik 这是真的,但 HDC 已经像一个不透明的指针并且非常小(4 个字节)。我不会真正看到按引用传递而不是按值复制的好处。会不会还有我遗漏的东西?
  • 是的。如果使用任何现代 C++ 编译器,使用 inline 函数返回 const referenceconst 通常可以防止胖手指在您的意思是 == 时输入 =,而无需任何额外开销。
猜你喜欢
  • 1970-01-01
  • 2013-11-02
  • 2023-03-05
  • 2014-02-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-19
  • 2014-07-26
相关资源
最近更新 更多