I would like to create an application in which I can define list of typed questions, then iterate over this list and ask user to enter answers, storing them in another list, then go over answers, validate them and provide a result.
My current naive approach is something like this:
class Question {
std::string message;
public:
Question(const std::string& msg) : message{msg} {}
std::string& getQuestion(void) const {
return this->message;
}
virtual ~Question(void) = 0;
};
Question::~Question(void) {}
template<class AnswerType>
class Prompt : public Question {
Prompt(std::string& msg) : Question{msg} {}
virtual ~Prompt(void) {}
};
class Answer<class T> {
T answ;
public:
Answer(const T& answer) : answ{answer} {}
T getAnswer(void) const {
return this->answ;
}
};
and I would like to do something like:
std::list< const Question* > whatToAsk{
new Prompt<int>{"Your age"},
new Prompt<std::string>{"Your name"},
new Prompt<float>{"Your weight"}
};
for(auto q in whatToAsk) {
Answer< "derived q template parameter" > a{};
std::cout << q->getQuestion() << ": ";
std::cin >> a;
// ... to be continued ...
}
storing questions (Prompt< T >) inside of std::list< const Question* >.
But problematic part for me is that I've to use downcasting (with runtime checking), virtual functions (runtime polymorphism) or double dispatch (again with runtime overhead).
My concern is that types are known during compilation, because list of questions will be hardcoded in the source code and I want to avoid runtime overhead and achieve compile-time static polymorphism.
How can I achieve this? Some kind of traits maybe?