我有一个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); }
);
用宏做这些是可能的,这只是一个坏主意。
这是一个坏主意,原因如下:
您得到的错误将基于文本替换。
调试通常是不可能的。
在基于宏的生成中可能会出现许多微妙的错误,这些错误很难发现。
有了模板,你得到了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;
因为:
- 你得到的错误将是基于文本替换的。
- 调试通常是不可能的。
- 在基于宏的生成中可能会出现许多小错误,这些错误很难被发现。