现在,我正试图在构造和操作方面抽象出C ++中矩阵和标量之间的差异。作为参考,LA lib是Eigen。
我想要这样的事情发挥作用:
template <typename T>
class Foo{
Foo(T _val) : val(_val) { ... };
... // implementation
T val;
}
operator+(Foo lhs, Foo rhs){
... // do something
}
所以当我这样做时:
Foo<MatrixXd> lhs(MatrixXd(2,2));
// implicitly calls Foo(10), becomes Foo<int>,
// and does elementwise addition for example
lhs + 10;
现在这一切都很好,但是每个人都知道模板只是鸭子打字,所以这些对象实际上是不同的,你不能把它们塞进一个通用的容器中,如:
vector<Foo> v; // obviously doesn't work; needs to have a typename specified
v.emplace_back(MatrixXd(2,2)); // and obvs these won't work either.
v.emplace_back(10);
所以我考虑过使用继承进行多态化,例如:
class Foo{
Foo(std::unique_ptr<Base> _val) { val = std::move(_val); };
Foo(int _val) { val = std::unique_ptr<int>(new int(_val)); };
... // implementation
std::unique_ptr<Base> val;
}
operator+(Foo lhs, Foo rhs){
auto ans = lhs.val + rhs.val; // something like this
...
}
但是这种方法会遇到丑陋的语法问题:
Foo lhs(new MatrixXdWrapper(3));
lhs + 2; // 2 gets implicitly copy constructed on the heap
我必须为每种类型指定一个,这是丑陋和不受欢迎的。
所以我的问题是:这些方法的问题是否有解决方法?或者我是否缺少第三种方法(可能是两者的混合),人们通常会将这些方法用于可以相互交互的通用容器类型?
谢谢!
答案 0 :(得分:0)
您可以在数字中添加矩阵吗? (当然,我在数学上问你)。据我所知,操作没有定义。我认为你的问题在于你的设计,而不是你的实现。没有人会理解你的代码,因为你不能添加矩阵和数字。
如果您想“添加”矩阵和数字,您可以执行以下操作:
Matrix<10,10> A;
Matrix<10,10>::All_ones I;
int c;
auto res = A + c*I;
每个了解线性代数的人都能理解这一点,并且非常适合实施。
我不知道这是不是你想要做的。
您还可以重载运算符+:
Matrix& operator+(Matrix& m, int c){
// for all i, j:
m(i,j) += c;
return m;
}
就是这样。我无法写出函数的正确签名,因为我不知道你的Matrix是如何定义的。也许你必须写下这样的东西:
template <size_t m, size_t n>
Matrix<m,n>& operator+(Matix<m,n>& m, int c)
{
...
}
或类似的东西。
当然,请记住还要定义“c + A”,如果您希望您的运算符也可以使用不同类型的整数(无符号,长整数)或双精度运算,则可以使用类型对运算符进行参数化,或者重载operator + for int,double ...