c – 基于宏定义的动态#include

我正在编写一个C应用程序,我想让开发人员在编译时选择用于特定问题的算法.两种算法都实现为实现公共接口的C类,并且是彼此的直接替换.它们都有一个.h和一个.cpp文件,并且驻留在一个子目录中(我们称之为impl /).

在我的Makefile中,我有类似的东西:

...
IMPL = default
...
binary: ... impl/$(IMPL).o
...
impl/%.o: impl/%.cpp impl-interface.h impl/%.h
...
%o: %.cpp ...
    $(CXX) $(CXXFLAGS) -DIMPL=$(IMPL) -c -o $@ $*.cpp

这个想法是用户应该能够键入make binary IMPL = thatimpl.

在任何想要使用用户选择的算法的文件中,我会这样做:

IImpl o = new IMPL();

但是,这要求我包含所选实现的头文件.不幸的是,C要求#include后跟“string”,< libfile>.您也可以使用建议使用的宏here,但它要求宏的参数是文字字符串.如果我使用:

#define QUOTEME(M)       #M
#define INCLUDE_FILE(M)  QUOTEME(impl/##M##.h)
#include INCLUDE_FILE(IMPL)

编译器将尝试包含文字字符串impl / IMPL.h,而不是将IMPL扩展为传递给make的任何内容,然后再扩展到编译器.

关于如何实现这一目标的任何指示都将非常受欢迎!

解决方法

由于预处理器的工作方式,您只需添加一个额外的间接层.这应该做:
#define QUOTEME(x) QUOTEME_1(x)
#define QUOTEME_1(x) #x
#define INCLUDE_FILE(x) QUOTEME(impl/x.h)

#include INCLUDE_FILE(IMPL)

Live example

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...