我有一个模板化的Prob类,可以用来组织来自不同问题集的各种编程问题。模板是问题编号。我该如何将不同的Prob对象存储在矢量或地图中?
这是类声明:
template<int ProbNum>
class Prob
{
std::string
text(std::ostream& out)
{
out << "Prob" << ((ProbNum < 10) ? "0" : "") << ProbNum << ": ";
}
void solve(std::ostream& out);
};
换句话说,如果我想为某个问题集的问题1声明一个对象,我会这样做
Prob<1> p1;
,然后将其存储在地图或向量中以备后用,以便用户可以在运行时对其进行调用(因为您无法将运行时参数传递给模板)。
编辑:我想将此类用作其他Prob类的抽象类。
Edit2:添加了更多代码以供澄清。
Edit3: 上半部分是Prob1.hpp
下半部分是我要如何使用它的驱动程序文件。
#include <iostream>
#include "Prob.hpp"
template<>
void
Prob<1>::solve(std::ostream& out)
{
out << "solution to prob1";
}
/***************************************************/
#include <iostream>
#include <cstdlib>
#include "Prob.hpp"
// Finished Problems
#include "Prob1.hpp"
int
main(int argc, char* argv[])
{
Prob<1> p;
p.solve(std::cout);
}
答案 0 :(得分:0)
模板类的每个实例构成一个不同的类型。因此,std::vector
之类的容器无法容纳Prob<ProbNum>
的不同值的ProbNum
。
如果在编译时知道所需的Prob<ProbNum>
实例的数量以及模板参数int ProbNum
的相应值,则可以将所有内容存储到tuple
中。例如:
auto mycollection = std::make_tuple(Prob<1>(), Prob<2>());
更通用的解决方案是为Prob
定义一个抽象基类。然后,如果您定义了指向基类的指针向量,则可以设法存储Prob<ProbNum>
对象的向量,其值具有int ProbNum
的不均匀。为此,您必须在基类中提供接口,即要通过基类的Prob<ProbNum>
访问的vector
的每个成员都必须为virtual
并且已经在基类中声明。
考虑以下示例:
#include <iostream>
#include <memory>
#include <vector>
struct base {
virtual void print() const = 0;
virtual ~base() = default;
};
template <int i>
struct derived : public base
{
virtual void print() const { std::cout << i << std::endl; }
};
int main()
{
std::vector<std::unique_ptr<base>> vec;
vec.emplace_back(new derived<1>());
vec.emplace_back(new derived<3>());
vec.emplace_back(new derived<5>());
for (auto& el : vec)
el->print();
return 0;
}
变量vec
本质上是指向derived<i>
类型的对象的指针的向量,其值i
不均匀。由于base::print()
是虚拟的,因此它可以正确解析为derived<i>
类的相应方法。
请注意,我使用了smart pointer来避免内存泄漏。
此外,声明virtual
为base
的析构函数很重要,请参见讨论Why should I declare a virtual destructor for an abstract class in C++?。