我有一个模板类template<typename T, typename R>
。 R的类型为vector<T*>
或list<T*>
。
我希望我的类重载[]
运算符,以便万一它是一个向量,我将使用内置的[]
运算符来提高效率,如果它是一个列表,我将使用迭代器实现它。
对我而言,这听起来像模板专业化的工作,所以我想写下这样的东西:
template<typename T, typename R>
T& tContainer_t<T, R>::operator[]( unsigned i )
{
//TODO with iterators
}
template<>
T& tContainer_t::operator[]<T, std::vector<T*> >( unsigned i )
{
// TODO with built in [] operator
}
这是错误的,编译器不允许这样做。
有没有办法让它工作,或者我应该使用typeid()
在运行时区分两个对象并采取相应的行动?
答案 0 :(得分:3)
使用模板执行此操作的方法是在可以部分专门化的类中创建静态辅助函数。但是,我要做的是:
template<typename T, typename R>
T& tContainer_t<T, R>::operator[]( unsigned i )
{
//assuming that the container refernce is name container;
typename R::iterator itr = container.begin();
std::advance(itr, i);
return *itr;
}
std::advance
保证对于具有随机访问迭代器的容器(例如vector),它是常量时间(基本上,它执行迭代器+ n),它可以像执行指针查找向量一样快。否则,它会iterator++
n次,这将是线性时间。 const版本将使用const_iterator,但基本相同。
这样做可以让您正确处理不同类型的容器(不仅仅是矢量和列表),而无需修改代码。
答案 1 :(得分:2)
您不必使操作员超载。库aleady包含重载函数来帮助您。 std::advance
将移动迭代器,利用operator+()
随机访问迭代器。
template<typename T, typename R>
T& tContainer_t<T, R>::operator[]( unsigned i )
{
typename R::iterator it = myContainer.begin();
std::advance(it, i);
return *it;
}