шаблонный код не работает, в то время как не шаблонный код работает! - PullRequest
3 голосов
/ 28 июня 2011

Я провел несколько часов, совершенно застряв, когда понял, что только в шаблонной версии моего кода есть ошибка.

В следующем коде, когда элементы pushing_back в myMap, исходные векторы myVec1 и myVec2 модифицируются и содержат мусор в конце выполнения. Если я удалю все шаблоны, просто заменив template<T> на double, то код работает нормально, как я и ожидал (исходные массивы не тронуты).

Забавно, если я вставлю cout в copy constructor, он не будет вызван, если код будет шаблонным. Но он вызывается, если я заменяю конструктор копирования на Vector<T2> исходным типом Vector<T>, и тогда все работает нормально.

Почему компилятор не узнает это T2==T, поскольку я использую только double?

(обратите внимание, код был сделан максимально коротким, чтобы показать ошибки - таким образом, я удалил средства доступа, сделал все общедоступным и т. Д.).

#include <vector>
#include <map>


template<class T>
class Vector{
public:
    Vector():n(0),data(0){};
    Vector(int N):n(N),data(new T[N]){};
    Vector(T x, T y):n(2),data(new T[2]){data[0]=x; data[1]=y;};
    template<class T2> Vector(const Vector<T2>& rhs):n(rhs.n), data(new T[n])
    {
        for (int i=0; i<n; i++)
            data[i] = T(rhs.data[i]);
    }   
    ~Vector(){delete[] data;}

    Vector& operator=(const Vector& rhs)
    {
        if (rhs.n != n)
        {
            if (data)
                delete[] data;
            data = new T[rhs.n];
        }
        n = rhs.n;
        memcpy(data, rhs.data, n*sizeof(T));
        return *this;
    }
    T& operator[](int i){return data[i];}
    const T& operator[](int i) const {return data[i];}
    int n;
    T* data;
};

typedef  Vector<double> Vectord;

template <class T> inline bool operator<(const Vector<T>& v1, const Vector<T>& v2)
{
    for (int i=0; i<v1.n; i++)
    {
        if (v1[i]<v2[i]) return true;
        if (v1[i]>v2[i]) return false;
    }
    return false;
}


int main(int argc, char** argv)
{
    std::vector<Vectord> myVec1(3);
    myVec1[0] = Vectord(1.,3.);
    myVec1[1] = Vectord(3.,3.);
    myVec1[2] = Vectord(1.,5.);

    std::vector<Vectord> myVec2(3);
    myVec2[0] = Vectord(4.,1.);
    myVec2[1] = Vectord(2.,5.);
    myVec2[2] = Vectord(6.,5.);

    std::map<Vectord, std::vector<Vectord> > myMap;
    for (int i=0; i<3; i++)
    {
        myMap[myVec1[i]].push_back(myVec2[i]);
    }



    return 0;
}

1 Ответ

9 голосов
/ 28 июня 2011

Шаблонный конструктор никогда не является конструктором копирования.

Итак, ваш класс использует автоматически сгенерированный конструктор копирования.

Приветствия & hth.,

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...