class EntityFactory
{
public:
EntityFactory(tinyxml2::XMLElement * pEntitiesNode);
~EntityFactory();
std::vector< std::unique_ptr<Entity> > && TakeEntities();
protected:
std::vector< std::unique_ptr<Entity> > mEntities;
};
当我调用TakeEntity时,我想将mEntities向量移到此类之外。
我应该返回我搬入的临时变量还是返回&amp;&amp;?
std::vector< std::unique_ptr<Entity> > && EntityFactory::TakeEntities()
{
return std::move(mEntities);
}
//or
std::vector< std::unique_ptr<Entity> > EntityFactory::TakeEntities()
{
return std::move(mEntities);
}
我想要的最终结果是我可以从其他地方调用此函数,并将字段向量移动到调用站点附近的变量中。
答案 0 :(得分:4)
正确的方法可能是按值返回和只有在实例可移动时才会这样做:
class Foo
{
std::unique_ptr<Bar> bar_;
public:
std::unique_ptr<Bar> get_bar() &&
{
return std::move(bar_);
}
};
这样,如果整个实例本身过期,您只能从该成员移动。一般来说,没有必要返回一个右值参考,因为这样可以获得很少的收益,而且通常不会保证安全。例如,假设您有Foo f();
,请考虑:
auto && p = f().get_bar();
如果按值返回,这是安全的,但如果您通过引用返回,则会成为悬空引用。
答案 1 :(得分:1)
如果禁用编译器copy elision
,请使用第一个,因为第二个将生成一个额外的临时变量,这会降低性能。
如果你没有禁用copy/move elision
,它们很可能是相同的(性能)。
答案 2 :(得分:0)
您不应该返回右值引用,并且可能会定义一个合适的实体:
#include <iostream>
#include <vector>
struct Entity {
int value;
Entity() {
static int n;
value = ++n;
}
Entity(Entity&&) = default;
Entity& operator = (Entity&&) = default;
Entity(const Entity&) = delete;
Entity& operator = (const Entity&) = delete;
};
class EntityFactory
{
public:
EntityFactory() {};
void insert(Entity&& entity) {
return mEntities.push_back(std::move(entity));
}
std::vector<Entity> Entities() {
return std::move(mEntities);
}
protected:
std::vector<Entity> mEntities;
};
int main() {
EntityFactory factory;
factory.insert(Entity());
factory.insert(Entity());
factory.insert(Entity());
std::vector<Entity> entities = factory.Entities();
for(const auto& e: entities) {
std::cout << e.value;
}
std::cout << std::endl;
if(factory.Entities().empty())
std::cout << "Empty factory\n";
}
目标(获取函数调用结果的值)将是复制省略值或rvalue构造值。