可以在不实际复制值的情况下实现转换,但前提是您必须小心使其工作。
当你用两组不同的参数实例化一个类模板时,你会得到两个不相关的不同类。除非您明确定义一个从另一个继承,例如:
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 绕过类型系统。但是您必须非常小心,对象具有相同的布局和不变量,以确保一切正常。如:
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';