Не перегружайте операторы типов, которыми вы не владеете. Вместо этого вы можете написать
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: Вы должны убедиться, что два вектора имеют одинаковый размер.