0

I am pretty inexperienced in C++ and I have a very strange problem when sorting a vector which is of type "T" that is a class member/attribute in a template class. The program compiles and run but calling "sort" over that attribute does work properly: it is not ordered at all after calling. However, I can create a local vector of type T inside a method and get ir ordered properly. What am I doing wrong?

I also include a simple and fast example of this situation. This is the template class (TempClass.h):

#include <vector>
#include <stdio.h>
#include <algorithm>
#include <functional>

template <class T> class TempClass{
    public:
        TempClass(T a, T b, T c){
            container.clear();
            container.reserve(3);
            container[0] = a; container[1] = b; container[2] = c;
        }

        void modifyAttribute(){
            printf("Previous state:\n");
            for(int i = 0; i<3; i++){
                printf("[%d] -> %d\n", i, container[i].read());
            }
            sort(container.begin(), container.end(), std::greater<T>());
            printf("Final state:\n");
            for(int i = 0; i<3; i++){
                printf("[%d] -> %d\n", i, container[i].read());
            }
        }

        void testLocally(){
            std::vector<T> localContainer(3);
            localContainer[0] = T(14); localContainer[1] = T(97); localContainer[2] = T(42);
            printf("Previous state:\n");
            for(int i = 0; i<3; i++){
                printf("[%d] -> %d\n", i, localContainer[i].read());
            }
            sort(localContainer.begin(), localContainer.end(), std::greater<T>());
            printf("Final state:\n");
            for(int i = 0; i<3; i++){
                printf("[%d] -> %d\n", i, localContainer[i].read());
            }
        }

    private:
        std::vector<T> container;
};

And a possible simple usage of it (Tester.cpp):

#include "TempClass.h"

class Value{
    public:
        Value(){
            this->val = 0;
        }

        Value(int val){
            this->val = val;
        }

        Value(const Value& reference){
            this-> val = reference.val;
        }

        bool operator >(const Value& other) const{
            printf("Ok...\n");
            return this->val > other.val;
        }

        int read(){
            return this->val;
        }

    private:
        int val;
};

int main(){
    TempClass<Value> object(Value(6), Value(17), Value(43));
    object.testLocally();
    object.modifyAttribute();
    return 0;
}

I do not really know what is happening :( Thank you very much in advance for your help.

Regards

ChesterLC
  • 3
  • 2
  • 2
    What is the output you get? – Anne Apr 09 '15 at 14:00
  • This is it: Previous state: [0] -> 14 [1] -> 97 [2] -> 42 Ok... Ok... Ok... Ok... Final state: [0] -> 97 [1] -> 42 [2] -> 14 Previous state: [0] -> 6 [1] -> 17 [2] -> 43 Final state: [0] -> 6 [1] -> 17 [2] -> 43 – ChesterLC Apr 09 '15 at 19:25

2 Answers2

1

Looks like you are calling reserve instead of resize and going out of bounds in your TempClass constructor here. See this thread for more details on the two functions.

Other than that it seems to be working, unless the code you are using is different than what you posted here.

On a side note, this->val is unnecessary. just use val.

Community
  • 1
  • 1
dwcanillas
  • 3,562
  • 2
  • 24
  • 33
  • Thank you very much for your help! I can give just a green tick but I also voted up your answer. Regards – ChesterLC Apr 09 '15 at 19:09
-1

When you call container.reserve(3); you increase the capacity of the vector (size of the internal storage), but the vector remains empty. operator[] doesn't insert elements, so when you do this:

container.reserve(3);
container[0] = a; container[1] = b; container[2] = c;

You're accessing some elements that don't actually exist in the vector, the vector is still empty after this.

The method that does what you want is resize(), which actually increases the size of the vector.

The constructor that you call in your testLocally method sets the initial size of the vector, not it's initial capacity, that's why in that method it works as you expect it to work.

Ionut
  • 6,436
  • 1
  • 17
  • 17