Получилось реализовать следующим образом, расширив под это smart pointer
1. запись значения
а) значение передается по указателю и записывается как void*
б) записывается тип (typename) в type_info, таким образом
2. чтение
а) по typename проверяют нужный тип
б) получаю значение с указанием того же typename (именно это неудобно, так как приходится явно указывать тип, зато его можно узнать из type_info)
class IOData : public std::shared_ptr<void> {
const std::type_info *ti;
public:
template <typename T> void reset(T *ptr) {
std::shared_ptr<void>::reset(ptr);
ti = &typeid(T);
}
template <typename T> bool isType() { return typeid(T) == *ti; }
template <typename T> T get() { return *(T *)std::shared_ptr<void>::get(); }
};
typedef std::vector<IOData> OutputData;