I'm trying to transfer parsed out the file names from regex match to the list of filesystem::path
objects.
I believe that matches are valid because for_each
for the same iterators and print to console work perfectly. However, I'm getting a segmentation fault running this code. What am I doing wrong? Is there a mistake in my lambda?
namespace fs = boost::filesystem;
std::forward_list<fs::path> results;
std::transform(std::sregex_iterator(file_data.begin(), file_data.end(), re),
std::sregex_iterator(), results.begin(),
[&](const std::smatch& m)->fs::path{
return root / fs::path(m[1].str());
});
GDB shows me this line as a place of error:
path& operator=(const path& p)
{
m_pathname = p.m_pathname;
return *this;
}
UPDATE: found the solution - use back_inserter(results)
instead of results.begin()
. However, why is that?
The
std::transform
algorithm's third parameter should be an iterator to the start of the range where the values should be written. Specifically, it works by overwriting the values in the range pointed at by the iterator with the transformed values. This means that there actually have to be values there to overwrite in the first place. In your case, you're writing to an emptyforward_list
, so there's nothing to write to, hence the crash.To fix this, consider replacing the last argument with a
back_inserter
, which will automatically create the space that's needed as the values are produced:More generally, to the best of my knowledge, all of the algorithms in
<algorithm>
that write to output ranges will assume that there are values available to overwrite in that range. If that isn't the case, consider using aback_inserter
or other type of insert iterator, which will automatically create the space that's needed for you.Hope this helps!