私のコードのテンプレート版だけがバグを持っていることに気づいたとき、私は数時間を過ごしました。テンプレート化されていないコードが動作している間、テンプレート化されたコードは動作しません!
myMap
のpushing_back要素を使用すると、元のベクトルmyVec1
とmyVec2
は変更され、実行の最後にガベージが含まれます。私はすべてのテンプレートを解除する場合は、ちょうどtemplate<T>
を二重に置き換えると、コードは正常に動作します(元の配列はそのままです)。
cout
をcopy constructor
に入れれば、コードがテンプレート化されていると呼び出されないというのは面白いことです。しかし、コピーコンストラクタをVector<T2>
で元のタイプのVector<T>
で置き換えると、それが呼び出されます。すべて正常に動作します。
私はdouble
しか使用していないので、なぜコンパイラはT2==T
を知らないのですか?
(注:できるだけコードを短くしてエラーを表示していますので、アクセサーを削除してすべてを公開しましたなど)。
#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;
}
は、あなたはそれを上に考えなければならない<'、この順序は、これにより少なくとも驚きの原則を傷つけ、実際のベクトル特性を表すものではありませんので。むしろ、それを 'strictweakordering'関数として宣言して、これを' map'に与えることをお勧めします。 (たとえ実装が、たとえstlのものであっても、この原則を傷つける例がたくさんありますが) – leftaroundabout