C++ 使用具有多个对象类型的模板

C++ 使用具有多个对象类型的模板,c++,C++,我需要编写一个容器模板类,其中T是一个对象,R可以是向量或列表。我需要支持常见的操作,如insert(T)size()等 我将一个名为T data的类成员作为列表或向量。问题是,如何编写代码,以便在运行时知道从std::list或std::vector调用哪个操作 例如,要获取容器中的第一个元素,我必须在vector case中调用data[0],在lists case中调用data.front()。我应该只使用typeid操作符吗 if (typeid(R) == typeid(vector

我需要编写一个容器模板类
,其中T是一个对象,R可以是
向量
列表
。我需要支持常见的操作,如insert(T)size()等

我将一个名为
T data
的类成员作为列表或向量。问题是,如何编写代码,以便在运行时知道从
std::list
std::vector
调用哪个操作

例如,要获取容器中的第一个元素,我必须在vector case中调用
data[0]
,在lists case中调用
data.front()
。我应该只使用
typeid
操作符吗

if (typeid(R) ==  typeid(vector<T*>))
  then ...
else if (typeid(R) == typeid(list<T*>))
 then ...
if(typeid(R)==typeid(向量))
然后。。。
否则如果(类型ID(R)=类型ID(列表))
然后。。。

还是有更好的办法

您应该使用模板专门化。你可以读一篇关于它的好文章。

你可以使用迭代器——迭代器是STL中的标准习惯用法。使用
begin()。您还可以将
push_back()
list
vector
一起使用,将元素添加到集合的末尾,
insert()
将元素添加到特定位置,
erase
从集合中删除元素。查看参考(,)了解更多常用函数


其思想是,模板中的方法调用在实例化点之前(特别是在模板函数调用之前)不会被检查,因此上述调用将绑定到模板中指定的确切集合类型

如果集合非常有限,您可以执行以下操作:

#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
}
#包括
#包括
使用名称空间std;
模板
X类;
类XImpl{};
模板
类X:XImpl{};
模板
类X:XImpl{};
int main()
{
Xa;
Xb;
xc;//错误
}
并将您的实现放入
XImpl


编辑:XImpl很可能也会被模板化。这段代码只是演示如何防范向量或列表以外的任何其他容器。当然,还要注意防止像
X

这样的糟糕组合。答案是姆丰塔尼尼给出的,使用专门化。
不过,对于您的具体示例,vector也支持front,vector和list尽可能具有相同的功能

任何时候您编写
时,如果
树中包含
typeid
,则说明您做得不对。在这种情况下,列表和向量共享了大部分接口,包括
front()
。这不会阻止使用其他也支持迭代器和
push_back()
。与其说我想阻止其他容器,不如说我想尽可能少地复制代码。仍然不确定从这里提到的内容和@MFontani的内容中,什么是更好的方法wrote@Michael-我认为,让我来解释一下,你也可以将这种方法用于其他集合(不仅仅是向量和列表),这是一件好事。在我的回答中,我没有强调这一点,因为您专门寻找向量和list@Michael-我的建议将“开箱即用”地适用于大多数所有STL容器(支持您希望使用的操作),而如果您采用mfontanini的方法,则需要编写更多代码以专门化每种情况