Skip to content

Instantly share code, notes, and snippets.

@david-german-tri
Created April 11, 2016 23:37
Show Gist options
  • Save david-german-tri/a8bd9d75865e3652fd46da6e5bf96310 to your computer and use it in GitHub Desktop.
Save david-german-tri/a8bd9d75865e3652fd46da6e5bf96310 to your computer and use it in GitHub Desktop.
Abstract Values, SimBody style
#include <cassert>
#include <iostream>
#include <memory>
#include <string>
template<typename T> class Value;
class AbstractValue {
public:
AbstractValue() {}
virtual ~AbstractValue() {}
virtual std::string GetTypeName() const;
// Returns the value if it’s of type Value<T>, or else asserts.
template<typename T> const T& GetValue() const {
const Value<T>* value = dynamic_cast<const Value<T>*>(this);
assert(value != nullptr);
return value->value();
}
};
std::string AbstractValue::GetTypeName() const {
return "abstract";
}
template<typename T> class Value : public AbstractValue {
public:
explicit Value(std::unique_ptr<T> value): value_(std::move(value)){}
virtual ~Value() {}
virtual const T& value() const { return *value_; }
std::string GetTypeName() const override { return typeid(T).name(); }
private:
std::unique_ptr<T> value_;
};
int main(int argc, char* argv[]) {
Value<double> pi(std::unique_ptr<double>(new double(3.14159)));
AbstractValue* abstract = &pi;
std::cout << abstract->GetValue<double>() << std::endl;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment