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

时间:2017-06-08 00:10:06

标签: c++ pointers memory-management c++14

我正在尝试构建一个带有转换保护措施的指针类来监控指针转换。具体来说,我希望它在断言内部执行dynamic_cast,并确保结果不是nullptr。不幸的是,如果指针没有指向类类型,它会给出一个编译时错误,指示不能使用dynamic_cast。

接下来我尝试了:

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

......但这种方法仍然无效,因为短路只发生在运行时;发生了同样的错误。

我的下一个想法是构建一个专门的convert_ok结构,如果两个指针都相同,则operator()返回true,否则返回dynamic_cast的bool结果。

我认为这种方法可行,但我觉得我必须遗漏标准库中的内容。 std::is_convertable接近,但是当从基类移动到派生类时,它只能在运行时知道转换是否合法...因此是动态转换。

为什么:因为我知道人们会问,我已经建立了一个Ptr模板,当设置NDEBUG时,该模板会缩减为常规指针,但如果发生内存问题,则会引用计数和跳闸断言(引用计数变为0)没有删除,删除后访问指针,多次删除指针等等。)它比智能指针更适合我,因为它在调试模式下执行更多簿记,而在设置NDEBUG时具有接近零的开销。它已经帮助我清理了一些棘手的指针玩杂耍,我现在正致力于扩展其功能。

1 个答案:

答案 0 :(得分:1)

11 #if GOOGLE_PROTOBUF_VERSION < 3002000
12 #error This file was generated by a newer version of protoc which is
13 #error incompatible with your Protocol Buffer headers. Please update
14 #error your headers.
15 #endif
16 #if 3002000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
17 #error This file was generated by an older version of protoc which is
18 #error incompatible with your Protocol Buffer headers. Please
19 #error regenerate this file with a newer version of protoc.
20 #endif
与测试结合使用,以确定std::enable_if是否适合SFINAE正确的断言。这样可以避免在dynamic_cast出错时使用dynamic_cast,例如:

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

我正在使用this boilerplate来实施测试。

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;
};

Demo