【发布时间】:2016-08-26 13:42:09
【问题描述】:
我只是在写一个 MathVector 类
template<typename T> MathVector
{
using value_type = T;
// further implementation
};
但是,该类被认为可以与基本类型一起使用,但也可以与复杂类一起使用
template<typename T> Complex
{
using value_type = T;
// further implementation
};
例如提供成员函数
template<typename T> Complex<T>& Complex<T>::operator*=(const Complex<T>& c);
template<typename T> Complex<T>& Complex<T>::operator*=(const T& c);
现在,对于 MathVector 类也定义了一个乘法:
template<typename T> MathVector<T>& MathVector<T>::operator*=(const MathVector<T>& c);
这对于T=double 来说很好,但对于T=Complex<double>,我希望能够与double 相乘,而无需先将其转换为Complex<double>(效率更高)。
代码也应该在 CUDA 设备代码中工作这一事实加剧了这种情况(为简洁起见,我省略了说明符 __host__ __device__)。这意味着标准库工具将无济于事。
首先我想到了一个额外的模板参数
template<typename T, typename U> MathVector<T>& MathVector<T>::operator*=(const U& c);
但这对我来说似乎很危险,因为U 可以比T 或T::value_type 多很多。 (事实上,我首先在 Complex 类中也有这个参数 - 编译器无法再决定使用哪个模板,是 Complex 类之一还是 MathVector 类。)
第二个思路是使用模板特化
template<typename T, typename U> MathVector<T>& MathVector<T>::operator*=(const U& c)
{
static_assert(sizeof(T) == 0, "Error...");
}
template<typename T> MathVector<T>& MathVector<T>::operator*=(const typename T::value_type& c)
{
// implementation
}
但这将不再适用于基本类型!
我在C++ Operator Overloading for a Matrix Class with Both Real and Complex Matrices 和Return double or complex from template function 中看到了这个(或非常相似的)问题的解决方案,但它们是使用标准库以CUDA 无法解决的方式解决的。
所以我的问题是:有没有办法重载适用于基本类型和服务于 value_type 但不适用于其他类型的运算符 - 不使用 nvcc 编译器会拒绝的 std:: 东西?
【问题讨论】:
-
我不确定这里有什么问题,你可以为它声明所有的重载,比如
template<typename T> MathVector<T>& MathVector<T>::operator*=(const MathVector<T>& c);、template<typename T> MathVector<T>& MathVector<T>::operator*=(const T& c);和template<typename T> MathVector<T>& MathVector<T>::operator*=(const typename T::value_type& c);。 -
您想要
U中的Complex<T>、T、MathVector<T>、MathVector<Complex<T>>中的4 个重载MathVector<Complex<T>>::operator*=(const U&);? -
@songyuano:问题是重载
template<typename T> MathVector<T>& MathVector<T>::operator*=(const typename T::value_type& c);不会为基本类型编译。 (顺便说一句,与第二个Mathvector<T>相乘是没有意义的,因为这将是一个标量积并会返回一个T,这在operator*=中没有意义 - 我为这种情况写了一个operator*,但这对问题并不重要。) -
@Jarod42 :请参阅我的第一条评论。我想要
MathVector<fundamental_type>::operator*=(const fundamental_type& c>、MathVector<Complex<T>>::operator*=(const Complex<T>& c)和MathVector<Complex<T>>::operator*=(const T& c)(但更笼统,正如我试图在问题中解释的那样) -
CUDA如何支持SFINAE/
decltype?,如你所愿MathVector<T>operator *= (const U&),T *= U有效
标签: c++ templates cuda operator-overloading