<T> 通过模板化运算符重载将 std::complex 乘以双倍
Multiplying a std::complex<T> by double via templated operator overload
假设定义了T operator*(const T &t, double d)
,我想将std::complex<T>
乘以double
。由于我需要对3种不同类型的T
执行此操作,因此我尝试为运算符编写一个模板函数。下面是T=float
的一个例子。
#include <iostream>
#include <complex>
template <typename T>
std::complex<T> operator*(const std::complex<T> &cd, double d) {
return std::complex<T>(cd.real() * d, cd.imag());
}
int main() {
std::complex<float> cf(1.0, 1.0);
std::complex<double> cd(1.0, 1.0);
double d = 2.0;
std::cout << cf * d << std::endl;
std::cout << cd * d << std::endl;
}
这给出了编译器错误
error: ambiguous overload for ‘operator*’ (operand types are ‘std::complex<double>’ and ‘double’)
原因很清楚,因为对于T=double
,我的重载与<complex>
中的实现冲突。首先将右侧强制转换为T
(即上例中的cf * float(d)
(不是一种选择,因为这会给我的一些数据类型带来很大的开销。
有什么方法可以告诉编译器它应该忽略我对T=double
的重载吗?
有什么方法可以告诉编译器,它应该忽略我的T=double重载吗?
您可以使用SFINAE:
template <typename T>
std::enable_if_t<!std::is_same<double, T>::value, std::complex<T>>
operator*(const std::complex<T> &cd, double d) {
return std::complex<T>(cd.real() * d, cd.imag());
}
但是您的实现与常规CCD_ 11不一致。
一种更安全的方法是引入您自己的类型来包装double
,类似于:
struct MyWrapper { double d; };
template <typename T>
std::complex<T> operator*(const std::complex<T> &cd, MyWrapper d) {
return std::complex<T>(cd.real() * d.d, cd.imag());
}
std::complex
已经以的形式定义了operator *
template< class T >
std::complex<T> operator*( const std::complex<T>& lhs, const T& rhs);
这与您自己的operator *
冲突,因为这两个函数都解析为获取std::complex<double>
和double
。
这意味着您只需要为std::vector<float>
和double
定义一个operator *
,就可以将过载更改为
std::complex<float> operator*(const std::complex<float> &cd, double d) {
return std::complex<float>(cd.real() * d, cd.imag());
}
然后
std::cout << cf * d << std::endl;
std::cout << cd * d << std::endl;
将起作用。
如果你想让重载保持一个模板函数,你可以使用SFINAE使它不编译,当你有一个std::complex<double>
时,使用
template <typename T, std::enable_if_t<!std::is_same_v<double, T>, bool> = true>
std::complex<T> operator*(const std::complex<T> &cd, double d) {
return std::complex<T>(cd.real() * d, cd.imag());
}
相关文章:
- <T> 通过模板化运算符重载将 std::complex 乘以双倍
- Cxx.jl 在 Julia Complex 和 std::complex 之间进行转换
- 仅当类型为 std::complex 时,才进行缩放
- std::complex<> in C++ 数学特殊函数:技术规范或提案
- 在 boost::<double>asio::buffer 中使用像 std::vector<std::complex> 这样的参数
- 将分配的内存与基本数据类型一起使用时,是否需要新放置? std::complex?
- (如何)我可以使用openmp矢量化"std::complex<double>"吗?
- 将 int 转换为双精度以执行 std::complex <double>的"*"操作
- _Complex 和 std::complex 之间的 C/C++ 互操作
- 优化两个 std::vector<std::complex> 的元素乘积,使用 <float>fftw_malloc() 分配
- 英特尔 ICPC 和 C++14:如何构建 std::complex
- C99 中的_Complex类型在 C++ 中的行为是否类似于 std::complex<>?
- 可以使用 memset 来填充 std::complex<float>s 数组吗?
- 我越来越"invalid conversion from `void*` to `std::complex<double>*"
- 在C++中使用 std::complex 创建复数无穷大<T>
- 重载标准运算符<<对于 std::complex
- 在复杂的LAPACK例程中使用std::complex
- std::complex的模板函数重载
- 正在初始化std::complex
- 将float*强制转换为std::complex<合法吗;浮动>*