c++泛型编程的精妙之处
boost mpl - C++ generic programming subtleties
我遇到的问题如下面的代码所示。
#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
s到我的构建,这导致一个boost-mpl-向量具有一个唯一的名称,其中包含我所有的插件。如果X
是唯一的结束名称,X_0 X_1 X_2是沿着这个向量的路径建立起来的名字,因为这个向量应用了mpl向量push_back
。
我知道 boost::preprocessor的抽象是关键,但我不想花时间去研究它,因为我正在对系统的一部分进行原型设计,最终将被编译时模块化。
所以,为了以后的参考,
- 为什么上面会出现错误?
- 正确的原始预处理器模式应该是什么样的?
- 正确的boost-preprocessor-library模式是什么样的?
使用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;
}
你可以看到为什么会出现错误
何不使用命名空间来一举两得呢?
// 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工作。
我不提倡杀生。
你的代码示例的问题是你在X和Y宏中有循环依赖:
Y定义为X+0, X定义为Y+1。因此,当展开宏时(在使用X时发生),就会出现问题。
添加:
似乎行为是这样的:当扩展宏X
在其定义名称X没有定义在预处理器名称空间,所以你看到X+0+1作为X扩展。
相关文章:
- 使用泛型编程的基本数据结构
- 在泛型编程中使用新的放置
- 在泛型编程中选择类型参数
- 在泛型编程C++重载增量运算符
- 处理C++泛型编程中的空分配
- 有关C++泛型编程的错误
- 在泛型编程中,需要在派生类中重新声明基类成员函数
- 将泛型编程与多态性混合在一起
- C++泛型编程 CRTP 基类继承自派生类型提供的类
- 泛型编程中带有关键字模板的规范
- 为什么泛型编程设计更喜欢自由函数而不是成员函数
- c++如何在泛型编程中声明自定义数组
- C++函数式和泛型编程[使用MySQL连接器示例]
- 继承和虚函数与泛型编程
- 虚函数与泛型编程
- 只使用<泛型编程中的比较
- c++泛型编程与模板和nullptr
- c++中的泛型编程和类中的类型定义
- 如何在c++中使用泛型编程来代替多态性
- 概念与复制构造函数冲突的泛型编程