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



我有一个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);
}

然后我可能会有另一个像这样的块:

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);
}
正如你所看到的一般模式是这样的:
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);
}

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

不要那样做。

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

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

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

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

这是一个坏主意,原因如下:

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

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

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

有了模板,你得到了c++编译器和调试器完全理解的东西,以及一堆"早期的";检查正确性。模板产生的错误很难,但比宏错误容易得多。

但是要在宏中执行:

#define MACRO(X,Y,Z) 
X x = Y(); 
Z(Y)

在换行符前使用,使"所有内容在同一行"。就c++预处理器而言(好吧,不止于此)

实际上,您正在生成一个非常长的c++代码位。由于c++不依赖换行符,所以宏可以工作。

尝试:

#define MY_MACRO(X, Y, Z)                   
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);                      
}

但我建议使用模板代替。

您可以使用反斜杠()将宏定义扩展另一行。例如,如果我输入:

#define MACRO1(x) std::cout << "macro1: " << x << std::endl;

可以改成:

#define MACRO1(x) std::cout << "macro1: " 
<< x << std::endl;

你还需要确保不要在定义的最后一行使用反斜杠,并且在使用反斜杠之前总是留一个空格。

编辑:

你也可以像这样使用模板:

#define my_template<int T> std::cout << T << std::endl;

但是我建议你这样做:

#define my_template(T) std::cout << T << std::endl;

因为:

  1. 你得到的错误将是基于文本替换的。
  2. 调试通常是不可能的。
  3. 在基于宏的生成中可能会出现许多小错误,这些错误很难被发现。

相关内容

最新更新