I am currently facing a design/language problem of sorts. I have 3 files, A,B,and C which have their own namespaces defined as A,B,and C respectively. Each namespace has exactly the same function signatures, only implemented differently (think a REST API call with different but similar APIs).
Now my aim is to be able to call these functions from the correct namespace without repeating the function name.
Ideally I'd like to do something like this:
#include <iostream>
#include "A.h"
#include "B.h"
#include "C.h"
enum ns {
A = 0,
B = 1,
C = 2
};
int main() {
auto NS = {A, B, C}; //these are the namespaces
if (condition){
int n = get_index();
NS[n]::myfunc();
}
}
where myfunc()
is defined, albeit differently, in each source file corresponding to A.h, B.h, and C.h.
Can someone tell me whether there is a way to do this, or suggest an alternate design pattern I should adopt? Thanks
To explain my problem more concretely, I have a DataReader
class which fetches data about say cars, from REST endpoints by vendors A, B, C and preprocesses them. I did think of making a class and subclassing them for different vendors, but then won't it be too complicated, having a vendor-specific class inside my DataReader
class?
You can create a base class/struct with a pure-virtual method myfunc()
,
and then make A
,B
and C
(each can reside in its namespace if you want them to, but it's not a must) derive from it and implement myfunc
.
You can then store them all in an array, and use a polymorphic call the invoke the proper method based on an index:
#include <array>
#include <iostream>
#include <memory>
struct Base {
virtual ~Base() = default;
virtual void myfunc() = 0;
};
namespace AAA // using a namespace is optional
{
struct A : public Base {
void myfunc() override { std::cout << "A::myfunc()\n"; }
};
}
namespace BBB // using a namespace is optional
{
struct B : public Base {
void myfunc() override { std::cout << "B::myfunc()\n"; }
};
}
namespace CCC // using a namespace is optional
{
struct C : public Base {
void myfunc() override { std::cout << "C::myfunc()\n"; }
};
}
int main() {
std::array<std::unique_ptr<Base>, 3> objs = {
std::make_unique<AAA::A>(),
std::make_unique<BBB::B>(),
std::make_unique<CCC::C>()
};
objs[0]->myfunc();
objs[1]->myfunc();
objs[2]->myfunc();
}
Output:
A::myfunc()
B::myfunc()
C::myfunc()
Notes:
struct
s instead of class
es is to make the demo a few lines shorter (save the public:
lines). You can use class
es of course instead of them.