Search code examples
c++templatesvector

I am trying to write templatized code to compare two vector but i am getting these error


#include <iostream>
#include <string>

#define BLOCK_SIZE 5

template<typename T>
class vec {
 T*ptr;
    int size;
    int capacity;
    public:
    
    vec():size(0),capacity(BLOCK_SIZE)
    {
        ptr = new T[capacity];
    }
    vec(int size1)
    {
        capacity=size1;
        ptr = new T[capacity];
        
    }
    void push_back(T val)
    {
        if(size==capacity)
        {
            T*ptr1 = new T[capacity];
            for(int i=0;i<size;i++)
            {
                ptr1[i]=std::move(ptr[i]);
            }
            delete[] ptr;
            ptr = nullptr;
            capacity+=BLOCK_SIZE;
            ptr = new T[capacity];
            for(int i=0;i<size;i++)
            {
                ptr[i]=std::move(ptr1[i]);
            }
            delete[] ptr1;
            ptr1= nullptr;
        }
        ptr[size++]=val;
    }
    
    T& operator[] (int num)
    {
        return ptr[num];
    }
    bool operator == (vec<T> obj)
    {
    if (this->size != obj.size) {
        return false; // Different sizes, not equal
    }
    else
    return true;
    }
    template<typename U>
    friend bool operator==(const vec<U>& lhs, const vec<U>& rhs);
};

template<typename T>
bool operator==(const vec<T>& lhs, const vec<T>& rhs) {
    if (lhs.size != rhs.size) {
        return false;
    }

    for (int i = 0; i < lhs.size; ++i) {
        if (lhs.ptr[i] != rhs.ptr[i]) {
            return false;
        }
    }

    return true;
}

int main() {
    vec<std::string> vec1;
    vec<int> vec2(10);
    vec2.push_back(100);
    vec1.push_back("abhinav");

    std::cout << vec1[0] << std::endl;
    std::cout << vec2[0] << std::endl;

    if (vec1 == vec2) {
        std::cout << "Same vectors" << std::endl;
    } else {
        std::cout << "Different vectors" << std::endl;
    }

    return 0;
}

below is error i am getting in gcc compiler

main.cpp: In function ‘int main()’:
main.cpp:86:14: error: no match for ‘operator==’ (operand types are ‘vec >’ and ‘vec’)
   86 |     if (vec1 == vec2) {
      |         ~~~~ ^~ ~~~~
      |         |       |
      |         |       vec<int>
      |         vec<std::__cxx11::basic_string<char>>
main.cpp:50:10: note: candidate: ‘bool vec::operator==(vec) [with T = int]’ (reversed)
   50 |     bool operator == (vec<T> obj)
      |          ^~~~~~~~
main.cpp:50:30: note:   no known conversion for argument 1 from ‘vec>’ to ‘vec’
   50 |     bool operator == (vec<T> obj)
      |                       ~~~~~~~^~~

How to modify this code so i can compare any two types of vector


Solution

  • Your operator== is expecting both vecs to be of the same type T.

    This actually makes sense.

    In this line:

    if (vec1 == vec2) {
    

    You are attempting to compare a vec<std::string> to a vec<int>. The compiler is emitting an error because it does not comply to your operator== declaration.

    Even if you did implement a operator== for such a case I don't see much point in it. The only case in which you can consider them really equal is if they are both empty, which is something you can easily test without convoluting the semantics of operator==.

    Having said that, if for some reason you need some special sematics like comparing a vec<int> to vec<string> after converting the strings to ints you should implement a specific overload for it.


    Update:
    As john commented above one use case for supporting comparison between different vec types could be for comparing numeric values (e.g. ints and floats). In this case you need to change the declaration to use 2 template parameters (like T, U):

    template<typename T, typename U> 
    bool operator==(const vec<T>& lhs, const vec<U>& rhs) { /*...*/ }