2011-06-06 62 views
5

我使用Boost.Filesystem來創建目錄中的文件列表。我使用boost::filesystem::recursive_directory_iteratorstd::copy將每個路徑作爲boost::filesystem::directory_entry對象放入std :: vector中。我想輸出到文件的std ::字符串了,所以我做了以下(\ n要避免使用< <):std ::轉換和移動語義

std::vector<boost::filesystem::directory_entry> buffer; //filled with paths 
... 
std::vector<std::string> buffer_native(buffer.size()); 
//transform directory_entry into std::string, and add a \n, so output is formatted without use of << 
std::transform(buffer.begin(),buffer.end(),buffer_native.begin(), [](boost::filesystem::directory_entry de)->std::string 
    { 
     std::string temp=de.path().string(); 
     temp+="\n"; 
     return temp; 
    } 
    buffer.clear(); 
    std::copy(buffer_native.begin(),buffer_native.end(),std::ostream_iterator<std::string>(out_file)); 

但是這個問題是,它創建了兩個載體中,原件立即被清除,因爲它不是必需的。這聽起來像是移動語義的完美場所,但n3242僅提供與C++ 98中相同的兩次變換重載。是否可以通過std::transform實現移動語義?如果不是,編寫自定義循環會更好嗎?

我在Windows XP上使用GCC 4.5.2(MinGW)。

回答

7

這看起來像make_move_iterator工作:

std::transform(make_move_iterator(buffer.begin()), 
       make_move_iterator(buffer.end()), buffer_native.begin(), 
       [](boost::filesystem::directory_entry&& de) -> std::string 
{ 
    // still makes copy :/ perhaps native() would work better, I don't know 
    std::string temp = de.path().string(); 
    temp += "\n"; 

    return temp; 
} 

一招迭代器僅僅是其移動其解引用的結果的迭代器。請注意,該類需要支持移動語義才能發揮作用。我不知道升壓FS是否會。


請注意,如果您的目標是在不同的行上輸出它們,那麼您做錯了。格式化的打印不應該要求輸入數據是以某種格式存在的,這會破壞目的。向數據添加換行符只是爲了格式化新行就是令人討厭的。它是由ostream_iterator爲您處理反正:

std::copy(buffer.begin(), buffer.end(), //    vvvv 
      std::ostream_iterator<std::string>(out_file, "\n")); 

任何事情更加複雜,使印刷拉姆達;請勿事先修改您的數據。

+0

只是幫助編譯器做RVO或通過返回無名的臨時移動:'return de.path()。string()+'\ n';' – 2011-06-06 03:56:09

+0

@Gene:無論如何它會移動它。 – GManNickG 2011-06-06 03:58:25

+0

謝謝。我不知道像'make_move_iterator'這樣的東西甚至存在(我還沒有完全讀過n3242)。我不認爲Boost.Filesystem支持移動語義,但我認爲他們計劃在未來。 – mmoran 2011-06-06 04:44:33