我有一个模板化的类,模板参数是类应保存的一些数据点的维数。该类具有专用版本MyClass<-1>
,允许在编译时未知的维度。
如何将特定类(比如MyClass<2>
)转换为更通用的形式?
更具体一点,这里有一些表明情况的人为例子。 (我使用的是特征库,但我认为一般原则这不重要)
using namespace Eigen;
template <std::size_t dim>
class MyClass {
public:
// Some constructors...
// A sample function:
Matrix<double, dim, 1> returnPoint();
// Some more functions here
private:
Matrix<double, dim, 1> point;
}
现在,假设我有以下代码段:
MyClass<2> *foo;
MyClass<Dynamic> *bar; // Dynamic is a Eigen constant, being defined as -1
// Do something here
// How to do this:
bar = some_cast<MyClass<Dynamic> *>(foo);
考虑问题我想我想要的东西是不可能存档而不实际复制点的值。任何人都能证明我的错误或证实了这个假设吗?
答案 0 :(得分:0)
可以在不实际复制值的情况下实现投射,但前提是您必须小心使其正常工作。
当您使用两组不同的参数实例化一个类模板时,您会得到两个不相关的不同类。除非您明确定义一个继承另一个,例如:
namespace with_inheritance {
template <class T, long sz>
class vector : public vector<T,-1> {
typedef vector<T,-1> base_t;
public:
vector() : base_t (sz) { }
};
template <class T>
class vector<T, -1> {
T* v_;
size_t sz_;
public:
vector(size_t sz) : v_ (new T[sz]), sz_ (sz) { }
~vector() { delete [] v_; }
T& operator[](size_t i)
{
if (i >= sz_) throw i;
return v_[i];
}
};
} // with_inheritance
所以在这种情况下你可以像:
一样进行施法namespace wi = with_inheritance;
wi::vector<double, 10> v;
wi::vector<double, -1>* p = &v;
std::cout << (*p)[1] << '\n';
如果没有继承关系,则不允许在它们之间进行转换。但是,您可以根据需要使用reinterpret_cast来绕过类型系统。但是你必须非常小心,对象具有相同的布局和不变量,以确保everthing工作正常。如:
namespace with_lots_of_care {
template <class T, long sz>
class vector {
T* v_;
size_t sz_;
public:
vector() : v_ (new T[sz]), sz_ (sz) { }
~vector() { delete [] v_; }
T& operator[](size_t i)
{
if (i >= sz_) throw i;
return v_[i];
}
};
template <class T>
class vector<T, -1> {
T* v_;
size_t sz_;
public:
vector(size_t sz) : v_ (new T[sz]), sz_ (sz) { }
~vector() { delete [] v_; }
T& operator[](size_t i)
{
if (i >= sz_) throw i;
return v_[i];
}
};
} // with_lots_of_care
然后施放如下:
namespace wc = with_lots_of_care;
wc::vector<double, 10> v;
wc::vector<double, -1>* p = reinterpret_cast<wc::vector<double, -1>*>(&v);
std::cout << (*p)[1] << '\n';