【发布时间】:2015-03-08 18:29:28
【问题描述】:
我有一些代码使用了从基类类型到子类类型的某种偷偷摸摸的强制转换,其中子类类型被指定为模板参数。我假设由于基类没有声明数据成员并且大小为零,因此基类指针地址将与子类相同,并且转换将成功。到目前为止,代码运行正常。
这是我正在做的简化版本:
template <class RangeT>
struct CppIterator {
CppIterator(const RangeT& range) { ... }
// ... methods calling RangeT's members
};
// Base class, provides begin() / end() methods.
template<class RangeT>
struct CppIterableBase {
CppIterator<RangeT> begin() {
return CppIterator<RangeT>( *(RangeT*)this ); // Is this safe?
}
CppIterator<RangeT> end() { ... }
};
struct MyRange : CppIterableBase<MyRange> {
// ...
};
我的问题基本上是 - 代码是否符合犹太教规?如果基为空,基指针是否总是等同于子指针?它依赖于实现吗?我以后会遇到麻烦吗?
它很好地解决了我的问题,但我有点怀疑。
【问题讨论】:
-
你(认为你)为什么需要这个?
-
我有多种范围类型 - 继承使我无需一遍又一遍地定义相同的 begin() 和 end() 方法。
-
我的意思是为什么需要强制转换它,而不是为什么需要具有模板类型的迭代器类。
-
此模式的名称是 CRTP。使用
static_cast,而不是 C 风格的演员表,如果你搞砸了继承,它可能会退化为危险的reinterpret_cast。 -
注意:你可以写
static_cast<RangeT &>(*this),而不是强制转换为指针和解引用
标签: c++ templates inheritance crtp