【问题标题】:Templates and universal references [duplicate]模板和通用参考 [重复]
【发布时间】:2020-02-10 12:22:23
【问题描述】:

我正在关注有关创建实体组件框架的教程。它使用组合(一个实体有一组组件)。

class Component
{
public:
    Entity* entity;

 //VIRTUAL VOID INITIALIZE, DRAW, UPDATE functions here
private:
    std::unique_ptr<Entity> m_pEntity;
};

class Entity
{
public:

//Add component function

    template <typename T, typename... TArgs>
    T& addComponent(TArgs&&... mArgs)
    {
        T* LComponent(new T(std::forward<TArgs>(mArgs)));
        LComponent->entity = this;
        std::unique_ptr<Component> uPtr{ LComponent };
        m_pComponents.emplace_back(std::move(uPtr));
        m_ComponentArray[getComponentTypeID<T>()] = LComponent;
        LComponent->ECS_init();
        return *LComponent;

    }
private:
    bool m_IsActive = true;
    std::vector <std::unique_ptr<Component>> m_pComponents;
    std::array<Component*, gMaxComponents> m_ComponentArray;
};

但是,作者没有很好地解释背后的逻辑,我无法理解 addComponent 函数的语法。特别是:

  • 为什么在将uPtr 添加到向量时需要将uPtr 转换为右值引用 m_pComponents.emplace_back(std::move(uPtr))

【问题讨论】:

  • 考虑到addComponent 根本没有返回任何东西,第一点变得没有意义。否则(如果您添加显式 return 语句)按值或按引用返回对象之间的区别与按值或按引用获取参数的函数非常相关。因此,如果您知道这种差异,您也应该了解返回类型的差异。
  • 您在一个问题中同时提出许多问题。通常,多个问题应作为多个单独的 Stackoverflow 问题提出。每个问题一个问题。
  • 至于new T...好吧,如果你改用new Component,那对你来说更有意义吗? new TT 类型的对象分配内存,然后构造该对象。 T 的类型无关紧要,它对 any T 的行为相同(不管是 Componentstd::vector&lt;Component&gt; 还是 int)。
  • 在“emplace_back(std::move(uPtr))”的情况下,它只是一个唯一指针的想法,即只有一个“拥有”某物的唯一实例。因此,为了插入向量,所有权必须“移动”到向量中。因此, std::move 用于实现这一目标。因此 std::move 在技术上是对 && 的强制转换,但在移动所有权时也使其可读。常见的误解是,人们感觉“对象”被移动了,但事实并非如此。这只是关于传递所有权。
  • std::move 既没有传输也没有移动,它只转换为 &&。采用右值 ref (&&) 的函数应该实现“请取得所有权!”的语义。在你的情况下,你有:std::vector &lt;std::unique_ptr&lt;Component&gt;&gt; m_pComponents; 所以向量内的指针对Component 对象具有唯一的所有权。因此,您使用new 在堆上创建一个新对象,并将m_pComponents.emplace_back(std::move(uPtr)); 的所有权传递给向量。 emplace_back( T&amp;&amp; ) 将真正接管所有权是约定俗成的,语言本身并不能保证。

标签: c++ templates rvalue-reference type-deduction


【解决方案1】:

为什么需要将uPtr 转换为右值引用 m_pComponents.emplace_back(std::move(uPtr)) 将其添加到 向量

这是因为uPtr 的类型为std::unique_ptr。这种类型不能复制!它只能移动。这是为了确保只有一个唯一的句柄拥有指针的所有权。

【讨论】:

  • 谢谢。我不知道 std::unique_ptr 需要移动而不是复制。先生,祝您有美好的一天。
  • @Daniel 如果您可以复制“唯一”指针,它将不再是“唯一”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-18
  • 2020-12-27
  • 1970-01-01
相关资源
最近更新 更多