如何反转模板依赖关系?

问题描述 投票:0回答:1

如果我想制作一个通用类模板 ResourceManager 来序列化其内容,调用 serialize 函数(或模板),如何调用下面的 serialize 可编译?

我不想声明这个函数模板,因为假设该项目将使用带有不同类型容器的ResourceManager,并且我不想声明所有可能的容器或在这样之后在我的源代码中间包含这个文件声明。

我可以以某种方式避免此声明或反转依赖关系,以便与

std
容器以及我的类型一起使用吗?

如果我只使用我的类型,我会让 serialize 成为它们的类成员,但我也想使用

std
容器,并且不包装它们。

#include <fstream>
#include <iostream>
#include <vector>

// With this forward declaration it works
// 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();
}

这是现场演示

c++ templates std
1个回答
0
投票

您可以通过向前声明

serialize
的通用版本来实现此目的,如下所示:

template <class T>
void serialize(std::ofstream& ofs, T& v);

它位于您当前注释掉的前向声明的位置,位于

ResourceManager
上方。

代码的其余部分现在工作方式完全相同,但您现在可以为其他类型创建

serialize
的专业化,而不需要任何额外的前向声明,包括
std
容器和您自己的自定义类型。

© www.soinside.com 2019 - 2024. All rights reserved.