我原来的问题非常简单:如何为标量类型(算术类型)和其他类(如Matrix类,Vector类,Tensor类)创建一个通用容器,并使其行为正确,就好像我做标量+矩阵一样,MatrixVector,TensorMatrix,标量+标量等
我正在尝试编写类型擦除类。我没有使用boost::type_erasure::any
。这是我自己的练习,我相信使用该库对于这个小目的来说是不必要的。
class var{
public:
template <typename T>
var(T val) : self_(std::make_unique<model<T> >(std::move(val))) {}
private:
friend var operator+(const var& lhs, const var& rhs);
class concept{
public:
virtual ~concept() = default;
virtual std::unique_ptr<concept> copy_() const = 0;
};
template <typename T>
class model final : concept {
model(T x) : data_(std::move(x)) {}
std::unique_ptr<concept> copy_() const override{
return std::make_unique<model>(*this);
}
T data_;
};
std::unique_ptr<concept> self_;
};
var operator+(const var& lhs, const var& rhs){
... // do something here
}
所以说我们有类似的东西:
var v1(3); // implicitly <int>
var v2(5.2); // implicitly <double> or <float>
v1 + v2; // implicitly <double> with value 8.2
同一班级可以照顾:
var v1(std::string("hello "));
var v2(std::string("world!"));
v1 + v2; // implicitly <std::string> with value "hello world!"
与此同时,我可以得到这些东西的载体:
vector<var> v;
v.emplace_back(std::string("hello ")); // no error
v.emplace_back(3); // no error either
我有想法提供加法器:
对于get_data(),class var{
...
private:
// Also make concept templated!
template <typename T>
class concept{
public:
virtual ~concept() = default;
virtual std::unique_ptr<concept> copy_() const = 0;
virtual T get_data();
};
template <typename T>
class model final : concept<T> {
model(T x) : data_(std::move(x)) {}
std::unique_ptr<concept<T>> copy_() const override{
return std::make_unique<model>(*this);
}
std::unique_ptr<concept<T>> adder(std::unique_ptr<concept<T>> rhs){
return data_ + rhs->get_data();
}
T data_;
};
// this defeats the purpose of type erasure!
std::unique_ptr<concept<T>> self_;
...
}
var operator+(const var& lhs, const var& rhs){
return { lhs.self_->get_data() + rhs.self->get_data() };
}
class var{
...
class concept{
public:
virtual ~concept() = default;
virtual std::unique_ptr<concept> copy_() const = 0;
// virtual ??? get_data(); What do I return here?
//
// template <typename T>
// virtual T get_data(); // virtual cannot be defined on function templates!
};
template <typename T>
class model final : concept {
...
std::unique_ptr<concept> add(std::unique_ptr<concept> rhs){
return data_ + rhs->get_data();
}
T data_;
};
std::unique_ptr<concept> self_;
};
var operator+(const var& lhs, const var& rhs){
return { lhs.self_->adder(rhs.self_) };
}
如果类型擦除可能不是解决此类问题的正确方法,我该怎么办? (我想避免组合的重载次数)否则,是否有的解决方案当前的设置?
对于背景的解释,我试图用矩阵进行标量乘法(反之亦然),矩阵乘法用矩阵,标量乘法用标量。(这显然在这种情况下,它们都是数字的,但在此,为了清楚起见,我添加了一个std::string
示例。