I'm writing a C++ application in which I want to let the developer choose what algorithm to use for a particular problem at compile time. Both algorithms are implemented as C++ classes that implement a common interface, and are drop-in replacements for each other. They both have a .h and a .cpp file, and reside in a subdirectory (let's call it impl/
).
In my Makefile, I have something along the lines of this:
...
IMPL = default
...
binary: ... impl/$(IMPL).o
...
impl/%.o: impl/%.cpp impl-interface.h impl/%.h
...
%o: %.cpp ...
$(CXX) $(CXXFLAGS) -DIMPL=$(IMPL) -c -o $@ $*.cpp
The idea is that the user should be able to type make binary IMPL=thatimpl
.
In whatever files wants to use the algorithm the user has chosen, I then do:
IImpl o = new IMPL();
However, this requires me to include the header file for the chosen implementation. Unfortunately, C++ requires #include
to be followed by either a "string"
, a <libfile>
. You can also use a macro as suggested here, but it requires the argument to the macro to be a literal string. If I use:
#define QUOTEME(M) #M
#define INCLUDE_FILE(M) QUOTEME(impl/##M##.h)
#include INCLUDE_FILE(IMPL)
The compiler will try to include the literal string impl/IMPL.h
, rather than expanding IMPL
to whatever was passed to make
and then to the compiler.
Any pointers on how I might achieve this would be very welcome!
You just need to add an extra layer of indirection, because of the way the preprocessor works. This should do:
#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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With