intArray1 = intArray1*2.5;
intArray1
タイプだと思いNumericArray<int>
ます。もしそうなら、T
ですint
。したがって、上記の式では、引数としてオーバーロードされた に渡されるため、2.5
adouble
が に変換されます。int
operator*(const int&)
つまり、2.5 (double) は 2 (int) になり、factor
基本的に2
. データの損失!
これを修正する 1 つの方法は、(クラス テンプレートのメンバーとして) 関数テンプレートを次のように使用することです。
template<class T> //this is for class templatwe
template<class U> //this is for function template
NumericArray<T> NumericArray<T>::operator * (const U& factor) const
{ //^^^^^^^ it is U now!
//your code
}
template
上記の定義で が2 つ使用されていることに驚かないでください。コメントは、その目的を示しています。それをよく理解していれば、パラメータがではU
なく にT
なり、 から独立しT
ているため、引数として渡すものは何でもよいことも理解できます。引数を渡す限り、データの損失はありません。
int
との積が であることがわかっているdouble
ので、関数に渡すときに関数からdouble
戻るのはなぜですか? 引数が の場合に返す方が理にかなっていると思います。したがって、以下は正しい実装のようです。NumericArray<int>
double
NumericArray<double>
double
template<class T> //this is for class templatwe
template<class U> //this is for function template
NumericArray<U> NumericArray<T>::operator * (const U& factor) const
{ //^^^ CHANGED
NumericArray<U> newArray(Size()); //CHANGED HERE TOO!
for (int i = 0; i < Size(); i++)
newArray[i] = factor * GetE(i);
return newArray;
}
待って!これは今正しいですか?とがの場合T
はどうdouble
なりますか? 上記は前のものとまったく同じ問題を抱えています!U
int
したがって、ここに 3 番目の試みがあります。
template<class T> //this is for class templatwe
template<class U> //this is for function template
NumericArray<decltype(std::declval<T>() * std::declval<U>())>
NumericArray<T>::operator * (const U& factor) const
{
typedef decltype(std::declval<T>() * std::declval<U>()) R; //define R
NumericArray<R> newArray(Size()); //CHANGED HERE!
for (int i = 0; i < Size(); i++)
newArray[i] = factor * GetE(i);
return newArray;
}
したがって、戻り値の型は次のとおりです。
NumericArray<R>
どこにR
ある:
decltype(std::declval<T>() * std::declval<U>());
T
との積の種類によって異なりますU
。それは今では正しく、少なくともはるかに優れています。
それが役立つことを願っています。