allenh1
allenh1

Reputation: 31

Pointer to a template Object

I cannot compile... I have no idea what's wrong here... This is where the errors occur:

void MainThread::run()
{
    Set<int>* p_test; p_test = new Set<int>;
    p_test->add(new int(9));
    std::cout<<"The set is: {";
    for (int x = 0; x < p_test->size(); x++)
        std::cout<< ", " << p_test->toString(x).toStdString().c_str();

    std::cout<<"}";

    std::cin.get();
}//test method

The error message is given as: "undefined reference to Set::Set()" and it shows up on the line that I try to use my class. My class compiles on its own... Below is the file "Set.h". Anybody have any idea as to how I can fix it? Thanks in advance.

#ifndef SET_H
#define SET_H

#include <functional>
#include <QList>
#include <QString>
#include <type_traits>
#include <exception>
#include <iostream>

template<typename T>
class Set {
public:
    //constructors
    Set();
    ~Set(){ delete []pType; }

    //functions
    const int & size(){ return m_size; }

    void add(const T * singleton);

    void empty();

    //operators
    inline T& operator [](int index){ return pType[index]; }

    template<class Y>
    friend Set<Y> operator *(const Set<Y>& s1, const Set<Y>& s2);//intersection
    template<class Y>
    friend Set<Y> operator *(Set<Y>& s1, Set<Y>& s2);
    template<class Y>
    friend Set<Y> operator +(const Set& s1, const Set& s2);//union
    template<class Y>
    friend Set operator -(const Set& s1, const Set& s2);//relative complement

    bool operator =(const Set& other)
    {
        delete []pType;//empty out the array

        /** Gets operator **/
        int x = other.size();
        pType = new T[x];
        for (int y = 0; y < x; y++)
            pType[y] = other[y];

        m_size = x;

        return true;
    }

    bool operator ==(const Set & other)
    {
        if(other.size() != size())
            return false;
        else
        {
            for (int x = 0; x < size(); x++)
                if (!other.has(pType[x]))
                    return false;
        }//end else
        return true;
    }//end equals operator

    /*template<typename Type>
    bool operator *= (const Set<Type> &lhs, const Set<Type> &rhs){
        //compile time statement (just to let people know)
        static_assert(std::is_same<Type1, Type2>::value, "Types are not equal!");
        return std::is_same<Type1, Type2>::value;
    }//operator for checking if two things are the same type */

    bool operator >(const Set &other)
    { /** Superset **/ return false; }
    \
    bool operator <(const Set *other)
    { /** Subset **/ return false; }

    Set& complement();
    bool isEmpty(){ return m_size == 0; }
    bool has(T* element);
    QString toString(int index);

private:
    T * pType;
    T * m_Type; //save the variable type.
    int m_size;
};

#endif // SET_H

I do have a constructor defined in a separate file.

Set<Y>::Set()
{
    m_size = 0;
    m_Type = new Y();//save a default value
}//create an empty set

Or do I need a different kind of constructor?

Upvotes: 1

Views: 151

Answers (2)

FKaria
FKaria

Reputation: 1072

Since you are writing a template class, all methods of the clas must be defined in the header file. Such as

  template<typename T>
  class Set {
    Set() { }    // <-- declaration and definition 
  };

This is because the compiler does not compile templated classes/functions until finds a place in the code that actually uses it, so your class "does not compile on its own".

To compile a template class, the compiler looks for the declaration and for the definition in the same file. Then the compiler will generate code that actually implements the function for the specific templated argument.

So put your function definitions in the same file when working with templates. If you want to create a specialization, then the specialized function is no longer a template and you have to put it in a separated file unless you declarte it inline.

Sorry if your head hurts after reading all of this... welcome to C++.

Upvotes: 1

Every method of your Set class must be defined in the header file. Your header file lacks the definition of Set::Set(), and of some other methods as well.

Upvotes: 2

Related Questions