Skip to content

Instantly share code, notes, and snippets.

@dannypsnl
Created July 25, 2019 15:31
Show Gist options
  • Save dannypsnl/a5c7b7a8044f6290af0f90f947266a35 to your computer and use it in GitHub Desktop.
Save dannypsnl/a5c7b7a8044f6290af0f90f947266a35 to your computer and use it in GitHub Desktop.
int or string, multiple dispatching to avoid duplicate define
#include <iostream>
#include <sstream>
#include <string>
struct Int;
struct String;
struct Visitor {
void print_t(int i);
void print_t(std::string str);
};
struct Decoder {
virtual ~Decoder() {}
virtual Decoder *decode(const std::string s) = 0;
virtual void accept(Visitor &v) = 0;
};
template <typename... Ts> struct TList;
template <> struct TList<> {
Decoder *decode(const std::string s) {
throw "must provide at least one type";
}
};
template <typename Head, typename... Tail> struct TList<Head, Tail...> {
Decoder *decode(const std::string &s) {
Head *value = new Head;
try {
return value->decode(s);
} catch (...) {
TList<Tail...> mg{};
return mg.decode(s);
}
}
};
struct Int : public Decoder {
int _i;
virtual Decoder *decode(const std::string s) override {
std::stringstream ss{s};
ss >> _i;
if (ss.fail()) {
throw "parse int fail";
}
return this;
}
virtual void accept(Visitor &v) override { v.print_t(_i); }
};
struct String : public Decoder {
std::string _s;
virtual Decoder *decode(const std::string s) override {
std::stringstream ss{s};
ss >> _s;
if (ss.fail()) {
throw "parse string fail";
}
return this;
}
virtual void accept(Visitor &v) override { v.print_t(_s); }
};
void Visitor::print_t(int i) { std::cout << "Int: " << i << '\n'; }
void Visitor::print_t(std::string str) {
std::cout << "String: " << str << '\n';
}
int main() {
TList<Int, String> mg{};
Visitor v{};
mg.decode("10")->accept(v);
mg.decode("abc")->accept(v);
}
@dannypsnl
Copy link
Author

By the way, I didn't handle memory correctly since just a little example

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment