C++ c++;投射一个唯一的向量\u ptr<;基地>;至唯一的\u ptr<;派生>;其中派生的是一个模板

C++ c++;投射一个唯一的向量\u ptr<;基地>;至唯一的\u ptr<;派生>;其中派生的是一个模板,c++,c++11,vector,unique-ptr,C++,C++11,Vector,Unique Ptr,我有以下情况: Base是一个基类。 T是一个模板,可以假定Base的任何派生类 底层为我提供来自Baseclass的数据,我需要将这些数据转换为上面层(编写代码的那一层)上的特定类,以便在用户级别上工作 代码如下: template <class T> class Access { std::vector<std::unique_ptr<T> getData(); } template <class T> std::ve

我有以下情况:

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

底层为我提供来自
Base
class的数据,我需要将这些数据转换为上面层(编写代码的那一层)上的特定类,以便在用户级别上工作

代码如下:

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;
}
模板类访问{
std::vector这将执行以下操作:

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"
}
struct Base{};
模板
派生结构:公共基{};
模板
std::vector getData()
{
//添加一些检查:
static_assert(std::is_base_of::value,“T必须从base派生”);
std::矢量数据;
//用某种方法填满它
std::矢量数据;
用于(自动项目:retData(&E)
{
auto t=std::unique_ptr(静态_cast(item.release());/(*)
retCastData.push_-back(std::move(t));
}
返回数据;
}
int main()
{
getData();//或“int”以外的其他类型
}
主要的事情发生在标有
(*)
的行中。在这里,惟一指针被释放,返回的原始指针被向下转换到派生类,然后插入到向量中。(这段代码的核心是受启发的,但删除的东西在这里被省略。)

请注意,
Derived
是一个类模板这一事实在这里一点都不重要(除此之外,您必须将
Derived
而不是
Derived
传递给
getData
)。

这样做:

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"
}
struct Base{};
模板
派生结构:公共基{};
模板
std::vector getData()
{
//添加一些检查:
static_assert(std::is_base_of::value,“T必须从base派生”);
std::矢量数据;
//用某种方法填满它
std::矢量数据;
用于(自动项目:retData(&E)
{
auto t=std::unique_ptr(静态_cast(item.release());/(*)
retCastData.push_-back(std::move(t));
}
返回数据;
}
int main()
{
getData();//或“int”以外的其他类型
}
主要的事情发生在标有
(*)
的行中。在这里,惟一指针被释放,返回的原始指针被向下转换到派生类,然后插入到向量中。(这段代码的核心是受启发的,但删除的东西在这里被省略。)


请注意,
Derived
是类模板这一事实在这里一点都不重要(除此之外,您必须将
Derived
而不是
Derived
传递给
getData
).

这看起来像是通常的
多态性向下广播
请参见。上面的代码显然不是不起作用的代码,因为它在完全不同的行上有错误。请提供实际的最小示例来说明实际问题(以及您尝试的解决方案),并包含生成的实际错误消息。您如何知道所有的
Base
实际上都是
T
s?这似乎是通常的
polymorphic_downcast
请参见。上面的代码显然不是不起作用的代码,因为它在完全不同的行上有错误。请提供实际的最少示例来演示实际问题(以及您尝试的解决方案),并包含实际生成的错误消息。您如何知道所有的
Base
实际上都是
T
s?rhe
staric\u assert
是冗余的,还是过于严格?我的意思是,如果类型完全不相关,
static\u cast
将出错?@Yakk:好的观点。是的,它在技术上是冗余的,但当然也有s直到出现更详细的错误消息。@Yakk:…实际上,我没有理由添加它…只是在其余消息之前写下它,它就留在那里:-)这不是异常安全的。如果
emplace\u back
抛出已被
release()释放的指针
'd被泄露。@T.C:谢谢你的彻底检查。我会做一个编辑,我认为可以纠正这个问题(因为
release()
unique\u ptr
构造函数都是
noexcept
).rhe
staric\u assert
是多余的还是过于严格的?我的意思是如果类型完全不相关,
static\u cast
将出错?@Yakk:这一点很好。是的,它在技术上是多余的,但当然还有更详细的错误消息。@Yakk:…实际上,对我来说,没有理由添加它…只是写下来在剩下的部分之前,它留在了那里:-)这不是异常安全的。如果
emplace\u back
抛出,已经
release()
'd的指针就泄漏了。@T.C:谢谢你的彻底检查。我会做一个编辑,我认为这是正确的(如
release()
唯一的\u ptr
构造函数都是
noexcept
)。