C++通用编程的微妙之处

发布于 2024-10-30 20:42:10 字数 1108 浏览 2 评论 0原文

我遇到的问题如下面的代码所示。

#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 的抽象是关键,但我还不想花时间研究它,因为我正在对最终将被编译的系统部分进行原型设计 -时间模块化。

那么,为了将来参考,

  1. 为什么我会收到上面的错误?
  2. 正确的原始预处理器模式应该是什么样的。
  3. 正确的 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 #includes 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,

  1. Why am I getting an error above ?
  2. What should the correct raw preprocessor pattern look like.
  3. What does the correct boost-preprocessor-library pattern look like.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

吃兔兔 2024-11-06 20:42:10

使用 g++ -E 编译会给出以下结果:

int main()
{

    std::cout << "should be 4: " << 4 << std::endl;

    std::cout << "should be 8: " << 4 + 4 << std::endl;






    std::cout << "expecting 5: " << X+0 +1 << std::endl;
}

因此您可以看到为什么会出现错误。

compiling with g++ -E gives this:

int main()
{

    std::cout << "should be 4: " << 4 << std::endl;

    std::cout << "should be 8: " << 4 + 4 << std::endl;






    std::cout << "expecting 5: " << X+0 +1 << std::endl;
}

So you can see why you get the error.

灰色世界里的红玫瑰 2024-11-06 20:42:10

为什么不一石二鸟并使用命名空间呢?

// a.hpp:

namespace a {
    const int module_id = 0;

    class module_a : extension_module< module_id > { … };
}

#undef last_module
#define last_module a

// b.hpp:

namespace b {
    const int last = last_module::module_id + 1;

    class module_b : extension_module< module_id > { … };
}

#undef last_module
#define last_module b

这是不太“聪明”的做法,并且会留下 ID 的痕迹。

但是,每次都需要以相同的顺序包含模块,ODR 才能发挥作用。

我不提倡捕杀任何鸟类。

Why not kill two birds with one stone and use namespaces.

// a.hpp:

namespace a {
    const int module_id = 0;

    class module_a : extension_module< module_id > { … };
}

#undef last_module
#define last_module a

// b.hpp:

namespace b {
    const int last = last_module::module_id + 1;

    class module_b : extension_module< module_id > { … };
}

#undef last_module
#define last_module b

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.

肤浅与狂妄 2024-11-06 20:42:10

您的代码示例的问题是您在 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文