Moze sie wydawac dosc magiczne, ale dziala tak, jak tego oczekujesz (C++11, sprawdzone na GCC 4.7.1)
Kopiuj
#include <iostream>
#include <vector>
#include <typeinfo>
#include <cassert>
struct complex
{
double re;
double im;
complex(double re = 0.0, double im = 0.0) : re(re), im(im) {}
};
complex operator+(complex lhs, const complex& rhs)
{
lhs.re += rhs.re;
lhs.im += rhs.im;
return lhs;
}
template<typename T>
class matrix
{
public:
private:
std::vector<std::vector<T>> data;
template<typename T1, typename T2>
friend auto operator+(const matrix<T1>& lhs, const matrix<T2>& rhs) -> matrix<decltype(lhs.data[0][0] + rhs.data[0][0])>;
};
template<typename T1, typename T2>
auto operator+(const matrix<T1>& lhs, const matrix<T2>& rhs) -> matrix<decltype(lhs.data[0][0] + rhs.data[0][0])>
{
typedef decltype(lhs.data[0][0] + rhs.data[0][0]) TOut;
matrix<TOut> res;
return res;
}
int main(int argc, char** argv)
{
matrix<int> a;
matrix<double> b;
matrix<complex> c;
assert(typeid(a) == typeid(matrix<int>));
assert(typeid(a+b) == typeid(matrix<double>));
assert(typeid(b+a) == typeid(matrix<double>));
assert(typeid(a+c) == typeid(matrix<complex>));
assert(typeid(c+a) == typeid(matrix<complex>));
}
Kodu jest duzo, bo podalem dzialajacy przyklad. Sama istota przeladowania tkwi tutaj:
Kopiuj
template<typename T1, typename T2>
auto operator+(const matrix<T1>& lhs, const matrix<T2>& rhs) -> matrix<decltype(lhs.data[0][0] + rhs.data[0][0])>
{
typedef decltype(lhs.data[0][0] + rhs.data[0][0]) TOut;
matrix<TOut> res;
return res;
}
Funkcja zwraca matrix<T>
, gdzie T
jest dedukowany na podstawie wyniku dodawania pol w dwoch macierzach i dziala tu normalna promocja typow. Np. jesli T1 == int
i T2 == double
, to wynikiem dodawania jest double
.
Edit Na Ideone nie dziala zaprzyjaznienie, przez co sypie bledami. Rozwiazaniem jest wyrzucenie deklaracji przyjazni z matrix
i upublicznienie pola data
. W praktyce z pewnoscia bedzie tam publiczny operator()(int row, int col)
(albo inny akcesor), z ktorego mozna skorzystac w funkcji bez potrzeby zaprzyjazniania jej.