我正在编写一个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
后跟a "string"
,a
.您也可以使用此处建议的宏,但它要求宏的参数为文字字符串.如果我使用:
#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)
实例