我需要编写一个容器模板类<T, R>
,其中T是一个对象,R可以是vector<T*>
或list<T*>
。我需要支持常见的操作,如insert(T)size()等...
我持有名为T data
的班级成员作为列表或向量。问题是,如何编写代码,以便在运行时我知道从std::list
或std::vector
调用哪个操作?
例如,要获取容器中的第一个元素,我必须在向量大小写中调用data[0]
,在列表大小写中调用data.front()
。我应该只使用typeid
运算符吗?
if (typeid(R) == typeid(vector<T*>))
then ...
else if (typeid(R) == typeid(list<T*>))
then ...
还是有更好的方法吗?
答案 0 :(得分:4)
您应该使用模板专业化。你可以阅读一篇关于它的好文章here。
答案 1 :(得分:2)
您可以使用迭代器 - 它们是STL中的标准习语。使用begin()
来获取指向集合开头的迭代器和end()
以获得结束(更准确地说,指向元素的迭代器“在集合中的最后一个之后”)。您还可以push_back()
同时使用list<>
和vector<>
将元素添加到集合的末尾,insert()
将元素添加到特定位置并{{1}从集合中删除元素。查看参考文献(vector,list)了解更多常见功能。
这个想法是在实例化之前不会检查模板中的方法调用(并且直到模板函数的调用为止),因此上面提到的调用将绑定到您在模板中指定的确切集合类型
答案 2 :(得分:0)
如果集合如此有限,你可以这样做:
#include <vector>
#include <list>
using namespace std;
template < typename T, typename V >
class X;
class XImpl {};
template < typename T >
class X< T, vector<T*> > : XImpl {};
template < typename T >
class X< T, list<T*> > : XImpl {};
int main()
{
X< int,vector<int*> > a;
X< double, list<double*> > b;
X<int, int> c; // error
}
并将您的实施放入XImpl
。
编辑:XImpl很可能也会被模板化。这段代码只是展示防止任何其他容器而不是矢量或列表。当然还要防范像X<int, vector<double*> >
这样糟糕的组合。
答案 3 :(得分:0)
答案是mfontanini给出的一个,使用专业化。 但是,对于您的具体示例,矢量也支持前端,矢量和列表尽可能具有相同的功能