c++ - C++ 模板 - 为复数和复数泛化标量积矢量图
问题描述
我正在尝试重载*
运算符以使用模板计算标量积vector<double>
和vector<complex<double>>
向量,并且在尝试了我所知道的一切之后我到达了这个:
#include <iostream>
#include <complex>
#include <vector>
using namespace std;
template<typename T> T operator* (const vector<T> &a, const vector<T> &b) {
T retvar; complex<double> c = 0;
for (int i = 0; i < b.size(); i++) c += conj(a[i])*b[i];
if (is_same<T, double>::value) retvar = c.real();
else retvar = c; // (*) the error is generated by this line
return retvar;
}
int main() {
vector<double> a, b;
a.push_back(5); b.push_back(3);
cout << a*b << endl;
return 0;
}
我想要做的是:我计算复数的标量积,然后我将它返回包含在模板给出的类型的变量中,以避免任何奇怪的转换。但是,g++ 在 (*) 行抛出以下错误:
error: assigning to 'double' from incompatible type 'complex<double>'
老实说,我已经没有想法了,有什么好方法可以摆脱这种情况而不会使操作员两次超载?
解决方案
不要重载您不拥有的类型的运算符。相反,你可以写一个
template <typename T>
struct my_vect {
std::vector<T> data;
T operator* (const my_vect<T>& other);
};
接下来,std::conj
无论参数的类型是什么,都返回一个复数。在我看来,这是不幸的,因为在数学中,复向量和非复向量的标量积没有区别。实数的共轭是实数。要恢复这个不错的属性,可以使用my_conj
:
template <typename T> struct is_complex : std::false_type {};
template <typename T> struct is_complex<std::complex<T>> :std::true_type {};
template <typename T>
T my_conj(const T&t) {
if constexpr (is_complex<T>::value) return std::conj(t);
else return t;
}
现在,对于复数和非复数向量,标量积的定义可以相同。完整示例:
#include <vector>
#include <complex>
#include <iostream>
#include <type_traits>
template <typename T> struct is_complex : std::false_type {};
template <typename T> struct is_complex<std::complex<T>> :std::true_type {};
template <typename T>
T my_conj(const T&t) {
if constexpr (is_complex<T>::value) return std::conj(t);
else return t;
}
template <typename T>
struct my_vect {
std::vector<T> data;
T operator* (const my_vect<T>& other) {
T result;
for (size_t i = 0; i < data.size(); i++) result += my_conj(data[i])*other.data[i];
return result;
}
};
int main() {
my_vect<double> x{{1,2,3}};
std::cout << x*x << '\n';
my_vect<std::complex<double>> y{{ {1,2} }};
std::cout << y*y;
}
PS:您应该检查两个向量的大小是否相同。
推荐阅读
- python - requests.exceptions.SSLError - 无法使用 python 模块
- mysql - MySQL 服务在处理脚本时关闭
- javascript - 如何为羽毛笔编辑器设置内容?
- android - API >23 中未显示开放街道地图
- linux - X509Certificate2 在 .NET Core 应用程序中的寡妇和 linux 中不同
- php - Xdebug 已安装,但 IDE 不听
- python-2.7 - 如何使用户需要 JSON
- spotfire - 在 Spotfire 表中排名、分组和设置标签
- java - 当第二个玩家做出选择时,如何排除第一个玩家的角色选择?
- user-interface - laravel 用户可编辑布局 - 有可能吗?