2014-02-12 38 views
0

當我打電話給TakeEntity時,我想將mEntities向量移到這個類之外。從類中移動矢量,返回&&或移動到臨時?

我應該返回一個臨時變量,我搬進去還是返回一個& &?

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); 
    } 

我想要的最終結果是我可以從其他地方調用此函數,並將字段向量移到呼叫站點附近的變量中。

回答

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(); 

如果按價值回報,但如果你通過引用返回將是一個懸掛引用這是安全的。

+0

這個語法的名字是什麼? std :: unique_ptr get_bar()&& – EddieV223

+0

@ EddieV223:該標準稱它爲* ref-qualifier *,所以你可以說「'get_bar'是右值限定的」。 –

1

如果您禁用編譯器copy elision,請使用第一個,因爲第二個將生成額外的臨時變量,這會降低性能。

如果您沒有禁用copy/move elision,它們很可能是相同的(性能)。

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"; 
} 

目標(價值得到函數調用的結果)將是一個複製的消隱值或右值推定價值。