c++ - 乘以 std::complex通过模板化运算符重载加倍
问题描述
假设已定义,我想将 a 与 a 进行多重播放std::complex<T>
。由于我需要为 3 种不同的类型执行此操作,因此我尝试为操作员编写模板函数。这是一个例子。double
T operator*(const T &t, double d)
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>
. 首先将右侧转换为 a T
(即cf * float(d)
在上面的示例中)不是一种选择,因为这会给我的一些数据类型带来很大的开销。
有什么办法可以告诉编译器它应该忽略我的重载T=double
吗?
解决方案
std::complex
已经定义了一个operator *
形式的
template< class T >
std::complex<T> operator*( const std::complex<T>& lhs, const T& rhs);
这与您自己的冲突,operator *
因为这两个函数都解析为采用 astd::complex<double>
和 a double
。
这意味着你真的只需要定义一个operator *
forstd::vector<float>
和 adouble
这样你就可以将你的重载更改为
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 使其无法在您有 a 的情况下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());
}
推荐阅读
- javascript - 实施 reCaptchav3 时未获得成功响应
- c# - 是否有任何服务器端对象用于在 c# 中保存所有用户的值?
- java - Apache Camel:如何使用自定义 AggregationStrategy
- javascript - 保存新的 div 顺序避免重复 sql 查询
- windows - 命令对可执行文件执行右键单击操作并选择“使用图形处理器运行”之类的选项
- pycharm - 使用 JetBrains DataGrip、PyCharm 连接到 Yandex.Cloud 中的 ClickHouse 托管 ClickHouse
- django - 如何在我们使用 inlineformset_factory 函数的表单集字段中添加类属性
- imacros - 使用 imacros 搜索进行数据提取
- android - 无法确定 androidx.appcompat:appcompat:1.0.2 的工件:没有可用于离线模式的缓存版本
- c++ - std::to_string 存储在 const char* 中