是否可以使用 C++ 宏来生成代码块?

ast*_*bia 1 c++ c++11

我有一个 C++ 程序,其中某些模式的代码块不断重复,我想知道是否可以使用 C++ MACROS 作为预处理器来自动生成此代码。更准确地说,我有一些看起来像这样的代码块:

for(std::size_t i=0;i< lc_.size(); i++)
{
  std::string str;
  state::MsData lc = data->lc(i);
  convert<data::ClassForLC>(lc.data(), str);
  lc_[i] = data::ClassForLC(str);
}
Run Code Online (Sandbox Code Playgroud)

然后我可能有另一个看起来像这样的块:

for(std::size_t i=0;i< mmop_.size(); i++)
{
  std::string str;
  state::MvData mmop = data->mmop(i);
  convert<data::ClassForMMOP>(mmop.data(), str);
  mmop_[i] = data::ClassForMMOP(str);
}
Run Code Online (Sandbox Code Playgroud)

正如你所看到的一般模式是这样的:

  for(std::size_t i=0;i< X_.size(); i++)
    {
      std::string str;
      Y X = data->X(i);
      convert<Z>(X.data(), str);
      X_[i] = Z(str);
    }
Run Code Online (Sandbox Code Playgroud)

我想知道是否可以定义一个宏 REPLACE(X,Y,Z) 用我作为参数传递的任何文本替换上面代码中的 X,Y,Z ?注意:我使用 C++11。谢谢

Yak*_*ont 5

不要那样做。

template<class Z, class X, class F>
void do_stuff( X&& x, F&& f ) {
  for(std::size_t i=0;i< x.size(); i++)
  {
    std::string str;
    auto tmp = f(i);
    convert<Z>(tmp.data(), str);
    x[i] = Z(str);
  }
}
Run Code Online (Sandbox Code Playgroud)

写一个模板。我们可以这样使用它:

do_stuff<data::ClassForMMOP>(
  mmop_,
  [&](std::size_t i){ return data->mmop(i); }
);
Run Code Online (Sandbox Code Playgroud)

用宏来做这件事是可能的,这只是一个坏主意。

由于多种原因,这是一个坏主意:

  1. 您得到的错误将基于文本替换。

  2. 调试通常是不可能的。

  3. 在基于宏的生成中可能会出现许多很难发现的微妙错误。

使用模板,您可以获得 C++ 编译器和调试器完全理解的内容,以及一系列“早期”正确性检查。模板产生的错误很难,但比宏错误要容易得多。

但要在宏中实际执行:

#define MACRO(X,Y,Z) \
  X x = Y(); \
  Z(Y)
Run Code Online (Sandbox Code Playgroud)

\就 C++ 预处理器(好吧,不止于此)而言,在换行符之前使用使“所有内容都在同一行上”。

实际上,您正在生成一段极长的 C++ 代码。由于 C++ 不依赖换行符,因此宏可以工作。