Disclaimer
I don't actually propose to apply this design anywhere, but I've been curious nonetheless how one would implement this in C++, in particular given C++'s lack of reflection. (I'm simultaneously learning and experimenting with C++11 features, so please do use C++11 features where helpful.)
The Effect
What I want to achieve is almost purely cosmetic.
I'd like a class that binds itself to an arbitrary number of, say, vectors, using referenced members (which, as I understand, must be initialized during construction), but provides "aliases" for accessing these vectors as members.
To give a minimal example, I want this to work—
std::vector<int> one;
std::vector<int> two;
std::vector<int> three;
Foo foo(std::make_pair('B', one),
std::make_pair('D', two),
std::make_pair('F', three));
foo.DoSomething();
where
class Foo
{
public:
// I'm using variadic templates here for sake of learning,
// but initializer lists would work just as well.
template <typename ...Tail>
Foo(std::pair<char, std::vector<int>&> head, Tail&&... tail) // : ???
{
// ???
}
virtual void DoSomething()
{
D.push_back(42);
std::cout << D[0] << std::endl;
}
private:
std::vector<int> A&, B&, C&, D&, E&, F&, G&; // and so on...
}
and also so that
std::cout << one[0] << std::endl; // outputs 42 from outside the class...
But you refuse to answer unless you know why...
Why would anyone want to do this? Well, I don't really want to do it, but the application I had in mind was something like this. Suppose I'm building some kind of a data analysis tool, and I have clients or operations people who know basic logic and C++ syntax, but don't understand OOP or anything beyond CS 101. Things would go a lot smoother if they could write their own DoSomething()
s on the fly, rather than communicate every need to developers. However, it's not realistic to get them to set up UNIX accounts, teach them how to compile, and so on. So suppose instead I'd like to build an intranet web interface that lets them write the body of DoSomething()
and configure what datasets they'd like to "alias" by an uppercase char
, and upon submission, generates C++ for a child class of Foo
that overrides DoSomething()
, then builds, runs, and returns the output. (Suspiciously specific for a "hypothetical," eh? :-) Okay, something like this situation does exist in my world—however it only inspired this idea and a desire to explore it—I don't think it'd be worth actually implementing.) Obviously, this whole uppercase char
ordeal isn't absolutely necessary, but it'd be a nice touch because datasets are already associated with standard letters, e.g. P for Price, Q for Quantity, etc.
The best I can do...
To be honest, I can't figure out how I'd make this work using references. I prefer using references if possible, for these reasons.
With pointers, I guess I'd do this—
class Foo
{
public:
template <typename ...Tail>
Foo(std::pair<char, std::vector<int>*> head, Tail&&... tail)
{
std::vector<int>[26] vectors = {A, B, C, D, E, F, G}; // and so on...
// I haven't learned how to use std::forward yet, but you get the picture...
// And dear lord, forgive me for what I'm about to do...
vectors[tail.first - 65] = tail.second;
}
virtual void DoSomething()
{
D->push_back(42);
std::cout << (*D)[0] << std::endl;
}
private:
std::vector<int> A*, B*, C*, D*, E*, F*, G*; // and so on...
}
But even that is not that elegant.
Is there a way to use references and achieve this?
Is there a way to make this more generic, e.g. use pseudo-reflection methods to avoid having to list all the uppercase letters again?
Any suggestions on alternative designs that would preserve the primary goal (the cosmetic aliasing I've described) in a more elegant or compact way?