Search code examples
c++templatesmemberspecialization

Template class member function specialization?


I went through tons of questions about this subject, but still failed to find an answer that I could use.

I have a template class, that is declared as follows:

template <typename Type, int inSize>
class sortedVector
{
    public:
         sortedVector();
         int getSize();
         int getAmountElements();
         bool add(const Type &element);

    private:
        Type *vector;
        int size;
        int amountElements;
};

The class is supposed to represent a sorted vector that can store any type of elements. This is a part of an assignment on a programming course. So far it seems that the main-function given in the assignment passes both integers and objects of type Polygon to the function. Polygon is a class I've done previously.

The vector is supposed to be sorted either by the area of the passed polygon-objects, or, of course, by value of the passed ints.

For this I think I'd need two different implementations of add(const Type &element). One that takes care of putting an int into its right place in to the vector and one that takes care of getting the area of the polygon and inserting it in the correct place in the vector.

We talk AFAIK about specialization of templates.

I've tried several different methods, but have so far just been met by compiler errors. What would be the best way to go about to achieve this?


Solution

  • In C++ a container that maintains an ordering will usually have a template argument for the comparison functor that is to be used to determine the ordering of elements. Have a look at std::set for example:

    template<typename Key, typename Compare = std::less<Key>, class Allocator = allocator<Key>>
    class set;
    

    You can probably skip the allocator for this exercise. The default Compare functor will use operator< but if I want to use something different I can instantiate set like this:

    typedef std::set<int, std::greater<int> > MySet;
    

    So, there is no need for you to use specialization here. How could you anyway? You cannot possible specialize for all classes that your sorted vector could be used with because you will never know how many of them are there.

    So this would make out declaration for sortedVector look like this:

    template<typename Elem, 
             typename Compare = std::less<Elem> >
    class sortedVector {
    public:
      // take the functor as a constructor argument in case it cannot be
      // default constructed
      sortedVector(Compare c = Compare()) : cmp_(c) {}
    
      // ...snip...
      void push_back(const Elem& x) {
        cont_.push_back(x);
        std::sort(begin(cont_), end(cont_), cmp_);
      }
    
    private:
      // trick just use a std::vector as storage and guarantee our sorted invariant
      std::vector<Elem> cont_;
    
      // we need to store the comparison functor in case it has state
      Compare cmp_;
    };
    
    #include<iostream>
    int main(){
       long long num;
       std::cin>>num;
       std::cout<<num;
    }