intArray1 = intArray1*2.5;
Tôi đoán intArray1
là loại NumericArray<int>
. Nếu đúng như vậy, thì T
là int
. Vì vậy, trong biểu thức trên, 2.5
là double
sẽ được chuyển đổi thành int
, vì nó được chuyển đến đối số quá tải operator*(const int&)
.
Điều đó cũng có nghĩa là, 2,5 (gấp đôi) trở thành 2 (int) và factor
về cơ bản là 2
. Mất dữ liệu!
Một cách để khắc phục điều này là sử dụng chức năng template (như thành viên của lớp mẫu) như:
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
}
Đừng để bị bất ngờ bởi hai sử dụng template
trong định nghĩa ở trên. Các ý kiến nói những gì họ đang cho. Nếu bạn hiểu rõ điều đó, thì bạn cũng hiểu rằng tham số bây giờ là U
thay vì T
, nó có thể độc lập với T
và do đó nó có thể là bất cứ điều gì bạn chuyển cho nó làm đối số. Không mất dữ liệu, như khi vượt qua đối số.
Bây giờ như bạn đã biết sản phẩm của int
và double
hóa ra là double
, thì tại sao trở NumericArray<int>
từ chức năng trong trường hợp khi bạn vượt qua double
với nó? Tôi nghĩ việc trả lại NumericArray<double>
trở nên hợp lý hơn nếu đối số là double
. Vì vậy, các sau dường như là đúng thực hiện:
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;
}
Chờ đã! Điều này có đúng không? Điều gì xảy ra nếu T
là double
và U
là int
? Ở trên có chính xác cùng một vấn đề như trước đó!
Vì vậy, đây là nỗ lực thứ ba:
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;
}
Vì vậy, các kiểu trả về là:
NumericArray<R>
nơi R
là:
decltype(std::declval<T>() * std::declval<U>());
mà phụ thuộc vào loại sản phẩm của T
và U
. Điều đó đúng bây giờ, ít nhất là tốt hơn nhiều.
Hy vọng điều đó sẽ hữu ích.
+1 Đó là một câu hỏi đơn giản, nhưng có giá trị cho người dùng mới. Mẫu không tầm thường! –