C++通用编程的微妙之处
我遇到的问题如下面的代码所示。
#include <iostream>
#define X 4
int main()
{
std::cout << "should be 4: " << X << std::endl;
#define Y X + 4
std::cout << "should be 8: " << Y << std::endl;
#undef Y
#define Y X+0
#undef X
#define X Y+1
std::cout << "expecting 5: " << X << std::endl;
}
错误:
test2.cc: In function ‘int main()’:
test2.cc:17: error: ‘X’ was not declared in this scope
我试图模拟的模式是在代码/构建级别扩展程序(很像 nginx 模块的方式在编译时连接)。我需要构建一个可扩展的编译时结构,通过将 #include
添加到我的构建中,该结构是可扩展的(可插入的),这会产生一个具有唯一名称的 boost-mpl-vector,其中包含所有我的插件。因此,如果 X
是唯一的最终名称,则 X_0、X_1、X_2 是在向量应用了 mpl-vector push_back
时沿途构建的名称。
我知道 boost::preprocessor 的抽象是关键,但我还不想花时间研究它,因为我正在对最终将被编译的系统部分进行原型设计 -时间模块化。
那么,为了将来参考,
- 为什么我会收到上面的错误?
- 正确的原始预处理器模式应该是什么样的。
- 正确的 boost-预处理器-库模式是什么样的?
The problem I have is illustrated in the following code.
#include <iostream>
#define X 4
int main()
{
std::cout << "should be 4: " << X << std::endl;
#define Y X + 4
std::cout << "should be 8: " << Y << std::endl;
#undef Y
#define Y X+0
#undef X
#define X Y+1
std::cout << "expecting 5: " << X << std::endl;
}
The error:
test2.cc: In function ‘int main()’:
test2.cc:17: error: ‘X’ was not declared in this scope
The pattern I am trying to emulate is extending a program at code/build level(much like how nginx modules are wired up at compile-time). I need to build up an extensible compile time structure, which is extensible(plugable) by adding #include
s to my build, that results in a boost-mpl-vector with a unique name that contains all of my plugins. So if X
is the unique end name, X_0, X_1, X_2 are the names that are built up along the way as the vector has mpl-vector push_back
applied to it.
I KNOW the abstractions of boost::preprocessor are key, but I don't want to commit the time to researching it just yet, as I'm prototyping part of the system that will eventually be compile-time modularized.
So, for future reference,
- Why am I getting an error above ?
- What should the correct raw preprocessor pattern look like.
- What does the correct boost-preprocessor-library pattern look like.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
使用 g++ -E 编译会给出以下结果:
因此您可以看到为什么会出现错误。
compiling with g++ -E gives this:
So you can see why you get the error.
为什么不一石二鸟并使用命名空间呢?
这是不太“聪明”的做法,并且会留下 ID 的痕迹。
但是,每次都需要以相同的顺序包含模块,ODR 才能发挥作用。
我不提倡捕杀任何鸟类。
Why not kill two birds with one stone and use namespaces.
This is way less "clever," and leaves a trail of ID's.
However, the modules do need to be included in the same order every time for the ODR to work.
I do not advocate killing any birds.
您的代码示例的问题是您在 X 和 Y 宏中存在循环依赖:
Y 定义为 X+0,X 定义为 Y+1。因此,当宏展开时(这发生在您使用 X 的地方),您就会遇到问题。
ADD:
行为似乎是这样的:在其定义名称 X 内扩展宏
X
时,未在预处理器名称空间中定义,因此您将 X+0+1 视为 X 扩展。The problem of your code sample is that you have circular dependency in X and Y macros:
Y is defined as X+0 and X is defined as Y+1. So when macros are expanded (that happens at the point where you use X) you have a problem.
ADD:
It seems that behaviour is this: when expanding macro
X
inside its definition name X is not defined in preprocessor name space so you see X+0+1 as X expansion.