自分のスニペットライブラリとテンプレートクラスの練習の両方のために、ユニバーサルベクトルクラスを作成しようとしています。基本的に、Vectorクラスは、精度がfloat、double、longdoubleなどのいずれであるかを選択できるようにテンプレート化されています。
私が遭遇した問題は、ベクトルをスケーリングする目的で*演算子をオーバーロードすることです。すべての作業オーバーロードとメンバー関数を除外すると、クラス定義は次のようになります。
#pragma once
#include <math.h> // for sqrt function when normalizing
template <typename T> class Vector;
template <typename T> Vector<T> operator*(const Vector<T>& obj);
template <typename T> class Vector {
private:
// Attributes:
static const int DIMS = 3;
T component[DIMS];
public:
enum {
X, Y, Z
};
public:
// Constructors:
Vector(void) {
for (int i=0; i<DIMS; ++i) {
component[i] = T();
}
}
Vector(T x, T y, T z) {
component[X] = x;
component[Y] = y;
component[Z] = z;
}
// Destructor:
~Vector(void) { }
// Scaling:
friend Vector<T> operator*(const Vector<T>& obj);
Vector operator*(const T scale) {
Vector<T> result = Vector<T>();
for (int i=0; i<DIMS; ++i) {
result.component[i] = component[i] * scale;
}
return result;
}
};
template <typename T>
Vector<T> operator*(const Vector<T>& obj) {
Vector<T> result = Vector<T>();
for (int i=0; i<DIMS; ++i) {
result.component[i] = obj.component[i] * this*;
}
return result;
}
私のメインメソッドには、次のコード行があります。
Vector<float> testVector1 = Vector<float>(1.0f, 0.0f, 0.0f);
Vector<float> testVector2 = Vector<float>(0.0f, 1.0f, 0.0f);
Vector<float> testVector3 = 10.0f * testVector1;
Vector<float> testVector4 = testVector2 * 10.0f;
1つのエラーを除いてすべてが正常にコンパイルされます。main()の4行目は正常に機能しますが(ベクトルにスカラーを乗算)、3行目(スカラーをベクトルに乗算)はエラーになります。
Error 1 error C2677: binary '*' : no global operator found which takes type 'Vector<T>' (or there is no acceptable conversion)
この問題についての私の最も良い推測は、コンパイラがオーバーロードしようとしているプリミティブの*演算子を認識しておらず、テンプレートに渡されるまでクラスが型を認識しないため、直接伝えることができないということです。私がやろうとしていることを達成する方法はありますか、またはテンプレートは演算子のオーバーロードのために常にクラスに従う必要がありますか?
更新: jwismarなどのおかげで、左利きのオーバーロードでの悪い試みを見つけました。クラス内の関数の定義は次のとおりです。
friend Vector<T> operator*(T scalar, const Vector<T>& obj);
そして、その実装は次のとおりです。
template <typename T>
Vector<T> operator*(T scalar, const Vector<T>& obj) {
Vector<T> result = Vector<T>();
for (int i=0; i<DIMS; ++i) {
result.component[i] = obj.component[i] * scalar;
}
return result;
}
クラスの上のオーバーロードの最初の宣言は現在template <typename T> Vector<T> operator*(T scalar, const Vector<T>& obj);
ですが、コメントアウトされているかどうかに関係なく、同じエラーが発生します。
次に、テンプレートと演算子のオーバーロードに関するより具体的な質問に移ります。エラーは未解決の外部ですが、コンパイラはコンパイル時に失敗します。
Error 1 error LNK2019: unresolved external symbol "class Vector<float> __cdecl operator*(float,class Vector<float> const &)" (??D@YA?AV?$Vector@M@@MABV0@@Z) referenced in function _main C:\Users\D03457489\Desktop\UVCTester\UVCTester\main.obj UVCTester
operator*(float, Vector<float>)
したがって、コンパイラは、の定義を見つけることはできても、実装を見つけることができないと言っています。したがって、新しい質問は次のとおりです。私の側での別の基本的な監視の結果ですか、それともこの方法でテンプレートを使用して、オペランドの左側が不明な演算子のオーバーロードを生成することはできませんか?