I have a project which has a number of classes, some of which have alternative implementations.
I am looking for a clean way to switch between these implementations as a -D
flag, without having to change every file which uses said class.
For example, I might have a class called Foo_A
. It is used in a variety of locations. But I also have an alternate called Foo_B
. It has some slightly different design assumptions, and might work better in some situations. It has the same interface however.
The approach that I am thinking if that when we want to use Foo_A
or Foo_B
, we call Foo
, and whichever has been defined is the one which will be used.
This answer here suggests that using templated type aliases might be a way to go.
I made a little MWE to try and test this concept out:
main.cpp
// clang++ -std=c++14 -pedantic -Wall main.cpp -o main -v
#include "choose.h"
#include <iostream>
int main(int argc, char *argv[])
{
Foo<int> foo;
std::cout << foo.member() << "\n";
return 0;
}
choose.h
#ifndef CHOOSE_H
#define CHOOSE_H
#ifdef A_SYSTEM
#include "foo_a.h"
template <typename T> using Foo = Foo_A<T>;
#else
#include "foo_b.h"
template <typename T> using Foo = Foo_B<T>;
#endif
#endif //CHOOSE_H
foo_a.h
#ifndef FOO_A_H
#define FOO_A_H
template<typename T>
class Foo_A
{
public:
Foo_A();
int member()
{
return 4;
};
};
#endif //FOO_A_H
foo_b.h
#ifndef FOO_B_H
#define FOO_B_H
template<typename T>
class Foo_B
{
public:
Foo_B();
int member()
{
return 2;
};
};
#endif //FOO_B_H
Unfortunately I am getting compile errors undefined reference to Foo_B<int>::Foo_B()'
.
I haven't been a#### foo_a.h
#ifndef FOO_A_H
#define FOO_A_H
template<typename T>
class Foo_A
{
public:
Foo_A()
{
val = 4;
};
int member()
{
return 4;
};
int val;
};
#endif //FOO_A_H
foo_b.h
#ifndef FOO_B_H
#define FOO_B_H
template<typename T>
class Foo_B
{
public:
Foo_B()
{
val = 2;
};
int member()
{
return val;
};
int val;
};
#endif //FOO_B_Hble to solve this issue yet. However, my first question is if this is a sensible design for what I'm trying to achieve? If so, what am I doing wrong in the MWE?
EDIT I hadn't defined my constructors, which solved the MWE problem.
foo_a.h#ifndef FOO_A_H
#define FOO_A_H
template<typename T>
class Foo_A
{
public:
Foo_A()
{
val = 4;
};
int member()
{
return val;
};
int val;
};
#endif //FOO_A_H
foo_b.h
#ifndef FOO_B_H
#define FOO_B_H
template<typename T>
class Foo_B
{
public:
Foo_B()
{
val = 2;
};
int member()
{
return val;
};
int val;
};
#endif //FOO_B_H