这是来自此处的后续问题: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 表达式中捕获字符串“文件名”,因为我只会使用它。我只需要访问 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
});
最佳答案
您似乎在这里混淆了不同层次的抽象。如果您要使用文件名,那么您基本上需要以下顺序:
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 值以指示该文件名是否是您想要在结果集中使用的文件名。处理文件内部内容的一切都将在该函数(或它调用的东西)内部发生。
关于C++ copy_if lambda 捕获 std::string,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20584766/