1

コンパイルできません...ここで何が問題なのかわかりません...ここでエラーが発生します:

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

エラー メッセージは、「Set::Set() への未定義の参照」と表示され、クラスを使用しようとした行に表示されます。私のクラスはそれ自体でコンパイルされます... 以下はファイル「Set.h」です。どうすれば修正できるか、誰にも考えがありますか?前もって感謝します。

#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

別のファイルで定義されたコンストラクターがあります。

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

それとも、別の種類のコンストラクターが必要ですか?

4

2 に答える 2

1

テンプレート クラスを作成しているため、クラスのすべてのメソッドをヘッダー ファイルで定義する必要があります。そのような

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

これは、コンパイラがテンプレート化されたクラス/関数を実際に使用するコード内の場所を見つけるまでコンパイルしないため、クラスは「単独でコンパイルされない」ためです。

テンプレート クラスをコンパイルするために、コンパイラは同じファイル内の宣言と定義を探します。次に、コンパイラは、特定のテンプレート化された引数の関数を実際に実装するコードを生成します。

したがって、テンプレートを操作するときは、関数定義を同じファイルに入れます。特殊化を作成する場合、特殊化された関数はテンプレートではなくなり、宣言しない限り、別のファイルに配置する必要がありますinline

ここまで読んで頭がおかしくなったらごめんなさい... C++ へようこそ。

于 2013-10-14T02:09:50.157 に答える