2011-06-06 31 views
5

Dizinde bir dosya listesi oluşturmak için Boost.Filesystem kullanıyorum. boost::filesystem::directory_entry nesnesi olarak her yolu bir std :: vektörüne koymak için boost::filesystem::recursive_directory_iterator ve std::copy kullanın. Bu sorun, iki vektör oluşturur edilir Ancakstd :: dönüşümü ve semantiği taşı

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

: Ben gerçi std :: dizeleri olarak dosyaya çıktı isteyen, bu yüzden aşağıdaki (\ n < < kullanımını önlemek için) did Orijinali, gerekli olmadığı için hemen temizlenir. Bu, semantikleri taşımak için mükemmel bir yer gibi geliyor, ancak n3242 sadece C++ 98'de olduğu gibi aynı iki aşırı yüklenmeyi sağlıyor. std::transform ile taşıma semantiği uygulamak mümkün mü? Değilse, özel bir döngü yazmak daha mı iyi olur?

Windows XP'de GCC 4.5.2 (MinGW) kullanıyorum.

cevap

7

Bu make_move_iterator için bir iş gibi görünüyor:

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

bir hareket yineleyici basitçe kendi KQUEUE sonucunu taşır Yineleyicinin. Sınıfın, bir anlam çıkarmak için bunun anlamını taşımayı desteklemesi gerektiğini unutmayın; Boost FS'nin yapıp yapmadığını bilmiyorum.


Amacınız bunları ayrı satırlarda çıkarmaksa, yanlış yapıyorsunuz demektir. Biçimlendirilmiş yazdırma, giriş verilerinin belirli bir biçimde olmasını ve bu amacı ortadan kaldırmasını gerektirmemelidir. Verilerinize yeni satırların eklenmesi, sadece yeni satırlara sahip olmak için biçimlendirilmesi kötü. Zaten ostream_iterator tarafından sizin için işlenir oldu:

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

şey daha karmaşık, baskı için bir lambda yapmak; Verilerinizi önceden değiştirmeyin.

+0

sadece derleyicinin RVO yapmasına ya da adlandırılmamış geçici olarak dönerek hareket etmesine yardımcı olur: 'return de.path(). String() + '\ n';' –

+0

@Gene: Her halükarda onu hareket ettirir. – GManNickG

+0

Teşekkürler. Make_move_iterator' gibi bir şeyin bile varolduğuna dair hiçbir fikrim yoktu (n3242'yi tam okumamıştım). Boost.Filesystem'in henüz semantik hareketleri desteklemediğini düşünmüyorum, ancak gelecekte yapmayı planladıklarını düşünüyorum. – mmoran

İlgili konular