C ++ copy_if lambda capture std :: string

时间:2013-12-14 14:58:19

标签: c++ c++11 lambda

这是一个跟进问题:C++ - Developing own version of std::count_if

我有以下功能:

// vector for storing the file names that contains sound 
std::vector<std::string> FilesContainingSound; 

void ContainsSound(const std::unique_ptr<Signal>& s)
{
    // Open the Wav file 
    Wav waveFile = Wav("Samples/" + s->filename_); 

    // Copy the signal that contains the sufficient energy 

    std::copy_if(waveFile.Signal().begin(), waveFile.Signal().end(), 
                 FilesContainingSound.begin(), [] (const Signal& s) {

                     // If the energy bin > threshold then store the 
                     // file name inside FilesContaining
                 }
}

但是对我来说,我只需要在lambda表达式中捕获字符串“filename”,因为我只会使用它。我只需要访问waveFile.Signal()即可进行分析。

有人有任何建议吗?

编辑:

std::vector<std::string> FilesContainingSound;
std::copy_if(w.Signal().begin(), w.Signal().end(), 
             FilesContainingSound.begin(), [&] (const std::unique_ptr<Signal>& file) {

                 // If the energy bin > threshold then store the 
                 // file name inside FilesContaining
             });

1 个答案:

答案 0 :(得分:4)

你似乎在这里混淆了不同的抽象层次。如果你打算使用文件名,那么你基本上想要这个顺序的东西:

std::vector<std::string> input_files;
std::vector<std::string> files_that_contain_sound;

bool file_contains_sound(std::string const &filename) { 
     Wav waveFile = Wav("Samples/" + filename);

     return binned_energy_greater(waveFile, threshold);
}

std::copy_if(input_files.begin(), input_files.end(),
             std::back_inserter(files_that_contain_sound),
             file_contains_sound);

目前我已将file_contains_sound放在一个单独的函数中,只是为了使其类型清晰 - 因为你正在处理文件名,它必须将文件名作为字符串,并返回一个bool,指示该文件名是否是结果集中所需的组之一。

实际上,你几乎从未真正想要将它实现为一个实际的函数 - 你通常希望它是某个类的一个对象,它重载operator()(并且lambda是一种简单的方法来生成一个这样的课)。所涉及的类型必须保持相同:它仍然需要将文件名(字符串)作为参数,并返回一个bool来指示该文件名是否是您在结果集中所需的文件名。处理文件内部内容的所有内容都会发生在该函数内部(或者它调用的内容)。