template class operators "unresolved externals"

222 views Asked by At

In my class :

#ifndef __MYVECTOR_CLASS__
#define __MYVECTOR_CLASS__

template<class Type>
class MyVector{
    ....
    MyVector& operator=(const MyVector& source); //works
    friend MyVector<Type> operator+(MyVector<Type> lhs, const MyVector<Type> &rhs); //doesnt
    ....
};

template<class Type>
MyVector<Type>& MyVector<Type>::operator=(const MyVector &v){
    if (_d != v._d){
        _d = v._d;
        _deleteArray();
        _createArray(_d);
    }
    _assignValues(v._vector, (v._vector + _d));
    return *this;
};


template<class Type>
MyVector<Type> operator+(MyVector<Type> lhs, const MyVector<Type> &rhs){
    if (lhs._d == rhs._d){
        for (int index = 0; index < lhs._d; index++){
            lhs._vector[index] += rhs._vector[index];
        }
    }
    return lhs;
};

#endif // __MYVECTOR_CLASS__

Didnt include other non operator functions, because they all work fine. Not a clue why its not working.

In source file:

int main(){
    MyVector<float> a(10);


    MyVector<float> b(10);
    a = b; // works alone
    a = a + b; //breaks
    return 0;
}

And errors:

  1. Error 1 error LNK2001: unresolved external symbol "class MyVector __cdecl operator+(class MyVector,class MyVector)"

  2. Error 2 error LNK1120: 1 unresolved externals

EDITTED:

added constructor.

template<class Type>
MyVector<Type>::MyVector(int size){
    _d = size;
    _createArray(_d);
    _assignValues(0);
}
1

There are 1 answers

3
dlf On BEST ANSWER

If you try to compile with coliru, you'll get this warning:

main.cpp:15:82: warning: friend declaration 'MyVector operator+(MyVector, const MyVector&)' declares a non-template function [-Wnon-template-friend] friend MyVector operator+(MyVector lhs, const MyVector &rhs); //doesnt

That should serve as a clue to what's going on. Change your code to:

template<typename T>
friend MyVector<T> operator+(MyVector<T> lhs, const MyVector<T> &rhs);

And it will build.

The friend function is itself a template with a template argument that is separate from class MyVector's.


Update: Although the above does seem to work, after reading this question and this one, I'm wondering if this might be more correct:

// forward-declare class MyVector
template<class Type>
class MyVector;

// forward-declare operator+()
template<class Type>
MyVector<Type> operator+(MyVector<Type> lhs, const MyVector<Type> &rhs);

template<class Type>
class MyVector{
    // declare that the already-declared operator+<>() is a friend
    friend MyVector<Type> operator+<>(MyVector<Type> lhs, const MyVector<Type> &rhs);
 };