Skip to content

Instantly share code, notes, and snippets.

@jsrois
Created April 3, 2017 12:17
Show Gist options
  • Save jsrois/bb75ead2e16ba0d02306a8c77ad1d108 to your computer and use it in GitHub Desktop.
Save jsrois/bb75ead2e16ba0d02306a8c77ad1d108 to your computer and use it in GitHub Desktop.
How can we create an std::vector for objects implementing an interface?
#include <iostream>
#include <vector>
#include <memory>
#include <sstream>
using namespace std;
struct RuleImpl {
virtual string serialize() const = 0;
};
struct Parameter : public RuleImpl {
string abbrev, name, info;
// Ouch!
//An aggregate is an array or a class (Clause 9) with no user-provided constructors (12.1),
// no brace-or-equal-initializers for non-static data members (9.2),
// no private or protected non-static data members (Clause 11),
// no base classes (Clause 10), and no virtual functions (10.3).
Parameter(string abbrev, string name, string info) {
this->abbrev = abbrev;
this->name = name;
this->info = info;
}
string serialize() const override {
stringstream stream;
stream << abbrev << " " << name << " " << info ;
return stream.str();
}
};
struct Flag : public RuleImpl {
string abbrev, name, info;
bool defaultValue;
Flag(string abbrev, string name, bool defaultValue, string info) {
this->abbrev = abbrev;
this->name = name;
this->defaultValue = defaultValue;
this->info = info;
}
string serialize() const override {
stringstream stream;
stream << boolalpha << abbrev << " " << name << " (" << defaultValue << ") "<< info ;
return stream.str();
}
};
// Composite (or is it Decorator?) to encapsulate the different implementations?
// Actually, we could use a template class
// and ducktype the Rule implementation.
struct Rule : public RuleImpl {
Rule(string abbrev, string name, string info)
{
impl = std::unique_ptr<RuleImpl>(new Parameter{abbrev,name,info});
}
Rule(string abbrev, string name, bool defaultValue, string info) {
impl = std::unique_ptr<RuleImpl>(new Flag{abbrev,name,defaultValue,info});
}
string serialize() const{
return impl->serialize();
}
unique_ptr<RuleImpl> impl;
};
int main() {
vector<Rule> objects;
objects.emplace_back("v","verbose",true,"Activate Verbosity");
objects.emplace_back("i","input-file","File to be processed");
/* Can't copy because stores unique_ptr (we can use shared_ptr instead)*/
for (auto& object : objects) {
cout << object.serialize() << endl;
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment