智能指针和裸指针是否有通用的方法?

3

我有一个关于C++模板的问题。

template <class Container>
void tryTriggers(const Container& entities)
{
  for (Container::const_iterator ent = std::begin(entities);ent != std::end(entities); ++ent)
  {
    if ((*ent)->isReadyForTriggerUpdate() && (*ent)->isAlive())
    {
      for (TriggerList::const_iterator trg = std::begin(_triggers);trg != std::end(_triggers); ++trg)
      {
         //Try(..) is a method takes *entity(entity's pointer) for parameters.
         //But my container was implemented with unique_ptr. 
         //ex) vector<unique_ptr<entity>> v;
         //So I used get() method for acquire raw pointer.

        (*trg)->Try((*ent).get());
      }
    }
  }
}

这段代码是用于一些容器的模板成员函数。

它仅适用于具有 isReadyForTriggerUpdate()isAlive() 方法的类。

Try(..) 是一个方法,其参数为 *entity(实体的指针)

在我的情况下,我使用了 unique_ptr 容器,因此我必须使用 get() 方法来获取原始指针。

该函数不会带来任何问题,但是......如果我使用一些使用原始指针的容器,例如

vector <entity*> v;

如果这样做,就会出现问题。

问题:我希望将其更加通用,以便与原始指针和智能指针一起使用。有什么解决方法吗?

STL中,有std::begin(con)来解决与con.begin()相关的迭代问题。因此,我期望有一些通用的方法,例如

std::begin(con)

针对上述问题。

虽然不相关,但如果您使用支持它的编译器,应该使用 auto 关键字替换 TriggerList::const_iterator,以节省打字和阅读这个巨大标识符的工作量。 - Colin Basnett
3个回答

3

除了 @Slava 的正确回答之外,一般来说,您可以编写一个模板函数,并为原始指针进行特化:

template<class T>                                                                                                                           
auto find_address_of(T &&p) -> decltype(p.get())
{
    return p.get();
}

template<typename T>
T *find_address_of(T *p)
{
    return p;
}

2
如果您获取解除引用指针的地址而不是调用std::unique_ptr::get(),那么这两种情况都应该可以工作:
(*trg)->Try(&**ent);

很好的答案 <padding> - Ami Tavory

0
(*ent).get()

由于我不了解您程序的其他部分,因此我假设这是唯一阻止函数工作的行:get是智能指针的成员函数,但不能与原始指针一起使用。我看到有两个解决方案可以解决这个问题:

解决方案1

使您的Try函数能够使用智能指针和原始指针。例如:

class A
{
    public:
        template <class SmartPointer>
        void Try(const SmartPointer& pointer)
        {
            Try(pointer.get());
        }

        void Try(entity* pointer)
        {
            /* Your code here */
        }
}

解决方案2

如果您无法更改正在使用的类,则可以创建一些函数将您正在使用的抽象类型转换为原始指针。一个用于智能指针,另一个用于原始指针。

template <class SmartPointer>
typename SmartPointer::element_type* getRawPointer(Pointer const& p)
{
    return p.get();
}

template <typename T>
T* getRawPointer(T* p)
{
    return p;
}

SmartPointer::element_type 是智能指针使用的类型(例如 std::unique_ptr<int> 的类型为 int)。请注意,您必须将其声明为 typename SmartPointer::element_type,以告诉编译器这确实是一种类型。

编辑:SmartPointer::pointer 更改为 SmartPointer::element_type*,以使其与较新的智能指针兼容。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接