【问题标题】:How can I test if an pointer type can be safely converted to another potiner type?如何测试指针类型是否可以安全地转换为另一种指针类型?
【发布时间】:2017-06-08 00:10:06
【问题描述】:

我正在尝试构建一个带有转换保护的指针类来监视指针转换。具体来说,我希望它在断言中执行 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 时开销几乎为零。它已经帮助我清理了一些棘手的指针杂耍,我现在正在努力扩展它的功能。

【问题讨论】:

  • "它对我来说比智能指针效果更好" - 不,它没有,而且对于需要维护您的代码的任何人来说,它都不会“更好地工作”。
  • 也许我应该提供更多细节。我正在开发高性能软件,需要尽可能优化某些核心领域。我同意它创建了一个更高的学习曲线来拥有一个“新”类型的指针,但我包含了良好的文档并使其尽可能直观以进行补偿。我可以举一些例子和基准来证明“工作得更好”,但我怀疑这不是你想要的。

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


【解决方案1】:

std::enable_if 与测试结合使用,以查看dynamic_cast 是否符合SFINAE 正确的断言。这将避免在格式不正确时使用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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-14
    • 2012-03-14
    • 2010-10-08
    • 1970-01-01
    相关资源
    最近更新 更多