In case I want to make a generic class template ResourceManager which serializes its content calling serialize function (or template), how to make call to serialize below compilable?
I don't want to declare a function template for vectors, because it is assumed that the project will use ResourceManager with different types of containers and I don't want to declare all possible containers or include this file in the middle of my sources after such declaration.
Can I somehow avoid this declaration or inverse the dependencies so that would work with std
containers as well as with my types?
In case I worked only with my types, I would make serialize their class member, but I want to work with std
containers, as well without wrapping them.
#include <fstream>
#include <iostream>
#include <vector>
// With this forward declaration it works for `std::vector`
// template <class T>
// void serialize(std::ofstream& ofs, std::vector<T>& v);
template <class Resource>
struct ResourceManager {
Resource& resourse;
ResourceManager(Resource& resourse) : resourse(resourse) {}
void store() {
std::ofstream ofs("vector_bin.vec", std::ios::trunc | std::ios::binary);
serialize(ofs, resourse);
}
};
template <class T>
void serialize(std::ofstream& ofs, std::vector<T>& v) {
auto size = v.size();
ofs.write((const char*)&size, sizeof(size));
ofs.write((const char*)v.data(), v.size() * sizeof(int));
}
int main()
{
std::vector<int> v = { 1,2,3 };
ResourceManager rm(v);
rm.store();
}
Here is the live demo.
You can replace serialize()
function with a trait class, and then partially specialize the trait for each container:
template <class Resource>
struct Serializer
{
static void write(std::ofstream& ofs, Resource& v) = delete;
};
template <class Resource>
struct ResourceManager {
Resource& resourse;
ResourceManager(Resource& resourse) : resourse(resourse) {}
void store() {
std::ofstream ofs("vector_bin.vec", std::ios::trunc | std::ios::binary);
Serializer<Resource>::write(ofs, resourse);
}
};
template <class T>
struct Serializer<std::vector<T>>
{
static void write(std::ofstream& ofs, std::vector<T>& v) {
auto size = v.size();
ofs.write((const char*)&size, sizeof(size));
ofs.write((const char*)v.data(), v.size() * sizeof(int));
}
};