2016-07-08 91 views
4

我手頭上有一些Foo的矢量,我想將它轉換成矢量Bar s和const。我能想到的最好的辦法是:轉換成const矢量

Bar foo2bar(const Foo& foo); 

std::vector<Foo> foos = {...}; 

const std::vector<Bar> bars = [&foos] { 
    std::vector<Bar> bars; 
    bars.reserve(foos.size()); 
    std::transform(foos.cbegin(), foos.cend(), 
        std::back_inserter(bars), 
        foo2bar); 
    return bars; 
}(); 

而且我覺得拉姆達的返回值應該由大多數編譯器被省略,所以這應該是接近理想。唯一的缺點是可能需要創建一個lambda,但我認爲這不是太多問題。

這種方法有什麼隱晦的問題,有沒有更好的方法(例如,更快,更清潔)? C++ 11可用。

回答

4

最簡單的解決方案是完全刪除const要求。您仍然可以將參考 - const公開給其他範圍。

如果沒有,這應該沒問題。 lambda體可能會被內聯,lambda的「創建」是一個編譯時過程,並且返回值將被移除或完全消失。實際上,你的方法非常優雅。

+0

是啊,這是我的團隊的風格指南的對象應該儘可能標註'const'(也許有時候有點迂腐,但是會讓超級安全的代碼),所以我必須嘗試找出一些東西。感謝您的建議! –

+0

@ZizhengTai:是的,我儘可能提倡'const'。但是你必須知道在哪裏畫線。 –

2

如果你真的無法忍受拉姆達的想法,那麼你可以達到提升的transform_iterator

#include <vector> 
#include <boost/iterator/transform_iterator.hpp> 

struct Foo {}; 
struct Bar {}; 

Bar foo2bar(const Foo& f) { 
    return Bar {}; 
} 

int main() 
{ 
    std::vector<Foo> foos = { }; 

    using boost::make_transform_iterator; 
    const std::vector<Bar> bars (make_transform_iterator(foos.begin(), &foo2bar), 
           make_transform_iterator(foos.end(), &foo2bar)); 
} 

然而,拉姆達擁有優化後沒有性能的損失,可以說不太神祕,所以我會鼓勵那。

1

另外,您可以將您的foo2bar()功能到您的Foo類作爲轉換操作符

struct Bar {}; 
struct Foo 
{ 
    // conversion opertor 
    operator Bar() const 
    { 
     // code to create Bar bar 
     return bar; 
    } 
}; 

int main() 
{ 
    std::vector<Foo> foos = {}; 

    const std::vector<Bar> bars(foos.begin(), foos.end()); 
}