0

I have some questions with the definition of a class inheriting STL vector. This class is suppost to publicly inherit from std::vector, but I keep getting the following error from the compiter. I am almost certainly that it is due to faulty including of <vector>, yet I don't know how to fix it.

In file included from useMVector.cpp
[Error] invalid use of incomplete type 'class MVector<T, size>'
In file included from MVector.cpp
     from useMVector.cpp
[Error] declaration of 'class MVector<T, size>'
recipe for target 'useMVector.o' failed

The relevant code is listed here:

useMVector.cpp:

#include <stdlib.h>
#include "MVector.cpp"

using namespace std;

int main() {
    return 0;
}

MVector.h:

#ifndef _MVECTOR_
#define _MVECTOR_

#include <iostream>
#include <stdlib.h>
#include <vector>

using namespace std;

template<class T, int size>
class MVector : public std::vector<T> {
    public:
        // constructer:
        MVector();
        // operator=, copy constructor and destructor from std::vector
        // iterator from std::vector

        // methodes:

        // addition with vector
        template<class T2>
        MVector<T, size> operator+(const MVector<T2,size>& y);

       ...
};

#endif // _MVECTOR_

MVector.cpp

#include "MVector.h"

template<class T, int size>
MVector<T, size>::MVector() : std::vector<T>::vector(size, 0) {};

template<class T2, class T, int size>
MVector<T,size> MVector<T,size>::operator+(const MVector<T2,size>& y) {

}

1 Answers1

2
template<class T2, class T, int size>
MVector<T,size> MVector<T,size>::operator+(const MVector<T2,size>& y)

Is not correct, you actually need to declare two separate templates, one for the class and one for the method:

template<class T, int size>
template<class T2>
MVector<T,size> MVector<T,size>::operator+(const MVector<T2,size>& y) {

}

Note that including .cpp files is not generally the correct approach. You should implement the templates in the header files. If you still want to keep the implementation separate you can do something like this:

A.h:

#pragma once

template<typename T>
class A
{
  A();
};

#include "A_impl.h"

A_impl.h:

template<typename T>
A::A() {}

You can name A_impl.h according to your own conventions, some code bases use names like A.ipp.

Deriving from std::vector (and most other standard library classes) is rarely appropriate, you should have a std::vector member instead.

Alan Birtles
  • 32,622
  • 4
  • 31
  • 60
  • Thanks for the answer. Is there a reason that you don't derive from STL classes or is it just convention? – Sebastian Apr 09 '20 at 10:43
  • They don't have virtual destructors so its not entirely safe to do so, see https://stackoverflow.com/questions/1073958/extending-the-c-standard-library-by-inheritance – Alan Birtles Apr 09 '20 at 12:38