Michael
Michael

Reputation: 22947

operator overloading and template specialization

I have a template class template<typename T, typename R>. R is of type vector<T*> or list<T*>.

I want my class to overload [] operator so that in case it is a vector I will use the built in [] operator for efficiency and in case it's a list I will implement it with iterator.

To me it sounds like a job for template specialization so I thought to write something like this:

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
}

This is wrong and the compiler doesn't allow this.

Is there a way to make it work, or should I use typeid() to differ the two objects at runtime and act accordingly ?

Upvotes: 0

Views: 1029

Answers (2)

Bo Persson
Bo Persson

Reputation: 92241

You don't have to overload the operator. The library aleady contains overloaded functions to help you. std::advance will move an iterator, taking advantage of operator+() for random access iterators.

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;
} 

Upvotes: 2

Dave S
Dave S

Reputation: 21058

The way to do it with templates is to make a static helper function in a class that can be partially specialized. However, what I would do is:

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 is guaranteed that for a container with random access iterators (such as vector), it is constant time (basically, it does iterator + n), it can be as fast as doing the pointer lookup vector performs. Otherwise, it does iterator++ n times, which will be linear time. The const version will use const_iterator, but is essentially the same.

Doing it this way will let you properly handle different types of containers (not just vector and list), without having to modify the code.

Upvotes: 3

Related Questions