如何在 vector.push_back(std::move(Object)) 之后 return 对象?

How to return object after vector.push_back(std::move(Object))?

我有一个包含这段代码的实体:

std::vector<Component*> Components;

template<typename T, typename... TArgs>
T& AddComponent(TArgs&&... args)
{
    T* component = new T(std::forward<TArgs>(args)...);
    
    Components.push_back(std::move(component));
    
    return Components.back();
}

问题是:

  1. 是否保证组件被移动和添加?
  2. 对返回对象的引用是否有效?
  3. 此功能是否需要任何额外检查(您认为)?

Is the component guaranteed to be moved and added?

不,因为您正在“移动”指针。而且分配不会像那样“移动”。事实上,如果您无论如何都在使用指针,则没有理由 std::move()

此外,就像@rustyx 建议的那样,您可能想使用 std::unique_ptr<Component> 而不是 Component*,因为它将负责在 vector 被销毁时释放内存。

Will the reference to the returned object be valid?

是的,但如果您添加其他组件,它可能会失效。请记住,back() 不会给您 Component*,而是 Component*&

所以您可能想要 return 实际上是 *component

Are there any additional checks necessary for this function (in your opinion)?

除上述之外 - 认真考虑避免使用指针向量以支持其他内容。动态多态性已经过时了:-P ...你考虑过变体吗?


整理一下:

#include <memory>
#include <vector>
#include <type_traits>

template<typename T, typename... TArgs>
T& addComponent(TArgs&&... args)
{
    static_assert(std::is_base_of<Component, T>::value,
       "Trying to add a 'component' whose type does not inherit Component");
    T* component = new T(std::forward<TArgs>(args)...);
    Components.emplace_back(static_cast<Component*>(component));
    return *component;
}

// ...

std::vector<std::unique_ptr<Component>> components;