【问题标题】:c++ Cast a vector of unique_ptr<Base> to unique_ptr<Derived> where derived is a template [duplicate]c ++将unique_ptr <Base>的向量转换为unique_ptr <Derived>,其中派生是模板[重复]
【发布时间】:2015-08-08 21:36:07
【问题描述】:

我有以下情况:

Base 是一个基类。 T 是一个模板,它可以假定Base 的任何派生类。

底层为我提供来自Base 类的数据,我需要将其转换为上层(编写代码的层)上的特定类才能在用户级别上工作。

代码如下:

template <class T> class Access {
       std::vector<std::unique_ptr<T> getData();        
}

template <class T>
std::vector<std::unique_ptr<T> getData()
{
      /// Get data from below layer
      std::vector<std::unique_ptr<Base>> retData; 

      retData = getDataFromBelowLayer();

      /// Now I have to cast Base to T
      std::vector<std::unique_ptr<T>> retCastData;

      for (auto &item : retData)
      {
          std::unique_ptr<T> = static_cast<T>(item); <<---- NOT WORKING
          retCastData.push_back(std::move(item));    <<---- NOT WORKING
      }

      return retCastData;
}

如何有效地将收到的unique_ptr´sBase 类的vector 转换为unique_ptr´sunique_ptr´svector 类型,如图所示。

感谢您的帮助。

【问题讨论】:

  • 看起来像平常的polymorphic_downcast
  • here
  • 上面的代码显然不是不工作的代码,因为它在完全不同的行上有错误。请提供实际的最小示例来演示实际问题(以及您尝试的解决方案),并包括生成的实际错误消息。
  • 你怎么知道所有Base实际上都是Ts?

标签: c++ c++11 vector unique-ptr


【解决方案1】:

这样就可以了:

struct Base {};

template<typename T>
struct Derived : public Base {};


template <typename T>
std::vector<std::unique_ptr<T> > getData()
{
      //add some checking:
      static_assert(std::is_base_of<Base, T>::value, "T must be derived from Base");

      std::vector<std::unique_ptr<Base> > retData; 
      //fill it somehow

      std::vector<std::unique_ptr<T> > retCastData;

      for (auto& item : retData)
      {
          auto t = std::unique_ptr<T>(static_cast<T*>(item.release()));   //(*)
          retCastData.push_back(std::move(t));
      }

      return retCastData;
}

int main()
{
    getData<Derived<int> >();   //or some other type than "int"
}

主要的事情发生在标有(*) 的行中。这里唯一指针被释放,返回的原始指针向下转换为派生类,然后插入向量中。 (这段代码的核心灵感来自this thread,但这里省略了删除器的东西。)

请注意,Derived 是一个类模板这一事实在这里根本不重要(除了您必须将 Derived&lt;/*some type*/&gt; 而不是 Derived 传递给 getData)。

【讨论】:

  • rhe staric_assert 是多余的,还是过于严格?我的意思是如果类型完全不相关,static_cast 会出错?
  • @Yakk:好点。是的,这在技术上是多余的,但当然还有更详细的错误消息。
  • @Yakk: ...在实践中对我来说没有理由添加它...只是在其余部分之前写下它并留在那里:-)
  • 这不是异常安全的。如果emplace_back 抛出,则已被release()'d 的指针泄露。
  • @T.C.:感谢您的彻底检查。我将进行一个我认为可以纠正的编辑(因为release()unique_ptr 构造函数都是noexcept)。
猜你喜欢
  • 2018-12-15
  • 2014-03-27
  • 2019-05-24
  • 2014-07-21
  • 2016-07-23
  • 2020-01-30
  • 1970-01-01
  • 2020-07-17
  • 2021-10-09
相关资源
最近更新 更多