【问题标题】:C++ way to implement loop macroC++实现循环宏的方法
【发布时间】:2020-11-10 10:12:20
【问题描述】:

我对 C++ 比较陌生,我目前正在根据给定的 C 代码创建一个类。 在这段代码中,有一些宏定义了 for 循环。我听说最好避免使用宏,所以我正在尝试(但失败)以不同的方式编写它们。

我查看了this question,它建议使用模板和仿函数,即使我没有达到我想要的效果。

我将举一个简单的例子。假设宏定义为

#define for_loop (g,u,v) \
for (u = g.attribute, v = g.otherAttribute ; u <= 20 ; u = g.updateAttribute, v = g.updateOtherAttribute)

并且它在代码的几个部分中用于不同的目的。

如果不使用 C++ 中的宏,您将如何实现它?

【问题讨论】:

  • 宏只是文本替换。如果没有更多上下文,您给出的示例很难推理。你可以做的就是不使用宏,只写出for循环。您并没有节省多少,而且您想要做的事情更加清晰。
  • 避免使用宏的最佳方法是不使用宏,而是编写 C++ 代码。你为什么不能在这里做?如果这需要是通用代码,请考虑使用template function。当与lambda expressions 之类的东西结合使用时,您可以做很多事情,而无需考虑宏。
  • 显示典型g的类型定义(你有很多不同的类型具有这些属性吗?)以及该循环体的示例。

标签: c++


【解决方案1】:

首先,如果您正在寻找这些宏的“愚蠢”替代品,那么您最好不要管它们。

如果您真的希望代码具有更好的可读性,请尝试找到有意义的惯用语,它们可能不会与这些宏一一对应。 IE。也许有时这个 for_loop() 可以用 range-for 循环替换,比如:

for (auto u : g) {
  ...
}

有时它可能会被调用一些标准函数(如std::find() 或其他东西...

如果你想实现完全符合这个宏的功能,你可以这样做:

void for_loop(g_type g, u_type u, v_type v, std::function<void(u_type, v_type)> func) {
  for (u = g.attribute, v = g.otherAttribute ; u <= 20 ; u = g.updateAttribute, v = g.updateOtherAttribute)
  {
    func(u, v);
  }
}

然后像这样使用它:

  for_loop(g, u, v, [<may require capture some used vars here>](u_type u, v_type v)
  {
    ... some code ...
  });

而不是原来的

  for_loop(g, u, v)
  {
    ... some code ...
  }

如果对 guv 的更改在循环后应该可见,则应使用引用而不是按值传递。

但我强烈不推荐这种方法。

【讨论】:

    【解决方案2】:

    如果不使用 C++ 中的宏,您将如何实现它?

    你可以写一个函数模板:

    void
    for_loop (auto& g, auto& u, auto& v, const auto& body)
    {
        for (u = g.attribute, v = g.otherAttribute;
             u <= 20;
             u = g.updateAttribute, v = g.updateOtherAttribute)
            body(g, u, v);
    }
    

    根据宏的使用方式,详细信息可能会有所不同。此示例紧跟宏,但可能有更好的方式来表达操作。我推荐更有意义的参数名称。

    【讨论】:

    • 函数参数中如何允许auto?它不能用 msvc 编译
    • @AryanParekh 这是 C++20 的东西。您可以在旧版本中用显式模板类型参数替换它们。
    • 哦,好吧,看到auto 我真的很困惑,这就是我问的原因:)
    • @AryanParekh:如果你不需要函数外的uv,你可以通过使函数的局部变量而不是参数来简化这一点。
    猜你喜欢
    • 2019-06-02
    • 2015-01-26
    • 2011-08-11
    • 1970-01-01
    • 2016-03-04
    • 1970-01-01
    • 2018-09-21
    • 2021-08-10
    • 1970-01-01
    相关资源
    最近更新 更多