如何测试指针类型是否可以安全地转换为另一种指针类型?



我正在尝试构建一个包含转换保护措施的指针类来监视指针转换。 具体来说,我希望它在断言内部执行dynamic_cast并确保结果不是 nullptr。 遗憾的是,如果指针未指向类类型,则会给出一个编译时错误,指示无法使用dynamic_cast。

接下来我尝试:

assert( (std::is_same<T,T2>() || dynamic_cast<T*>(in_ptr)) );

。但是这种方法仍然不起作用,因为短路只发生在运行时;发生了相同的错误。

我的下一个想法是构建一个专门的convert_ok结构,如果两个指针相同,则其运算符()返回true,否则返回dynamic_cast的布尔结果。

我认为这种方法会奏效,但我觉得我一定从标准库中缺少一些东西。std::is_convertable接近,但是当从基类移动到派生类时,它只能在运行时知道转换是否合法......因此动态演员表。

原因:因为我知道人们会问,所以我构建了一个 Ptr 模板,当设置 NDEBUG 时,它会减少到一个常规指针,但如果发生内存问题,引用计数和 trips 会断言(引用计数在不删除的情况下变为 0,删除后访问指针,多次删除指针等)对我来说,它比智能指针效果更好,因为它在调试模式下可以做更多的簿记,同时在设置 NDEBUG 时具有接近零的开销。 它已经帮助我清理了一些棘手的指针杂耍,我现在正在努力扩展它的功能。

std::enable_if与测试结合使用,以查看dynamic_cast是否与 SFINAE 正确的断言格式良好。这将避免在格式不正确时使用dynamic_cast,例如:

强制转换为非类类型或
  • 从非类类型转换,或
  • 从非多态类类型A转换为类类型B其中B不是可访问的A基础。

我正在使用这个样板来实现测试。

template <typename T, typename U>
using dynamic_cast_r = decltype(dynamic_cast<U*>(static_cast<T*>(nullptr)));
template <typename T, typename U>
using can_dynamic_cast = can_apply<dynamic_cast_r, T, U>;
template <typename T>
class foo
{
public:
foo(T *p) : p(p) { }
public:
template <typename U>
typename std::enable_if<can_dynamic_cast<T, U>::value, bool>::type convert_ok()
{
return dynamic_cast<U*>(p) != nullptr;
}
template <typename U>
typename std::enable_if<!can_dynamic_cast<T, U>::value, bool>::type convert_ok()
{
return std::is_same<T, U>::value;
}
private:
T *p;
};

演示

最新更新