Home > Blockchain >  std::transform applied to data member of sequence's element
std::transform applied to data member of sequence's element

Time:11-23

Please help me to find a more elegant way to rewrite this snippet using std::transform or similar algorithm:

for (auto& warning : warnings)
{
    NormalizePath(warning.path, GetParsedPathLength(warning.path), longestPathLength);
};

Where warning is a struct.

This is what I came up with:

std::transform(begin(warnings), end(warnings), begin(warnings),
    [longestPathLength](auto& warning)
    {
        NormalizePath(warning.path, GetParsedPathLength(warning.path), longestPathLength);
        return warning;
    });

But it requires a copy of full data-structure. Is there a way to create a modifiable view of a original sequence that contains only path member? So transform could be rewritten only accepting and returning modified path. And in the end all the changes should affect original warnings sequence.

CodePudding user response:

With ranges (C 20), you might "shorter" first version to:

for (auto& path : warnings | std::views::transform(&Warning::path))
{
    NormalizePath(path, GetParsedPathLength(path), longestPathLength);
}

CodePudding user response:

You can potentially create some temporary function through lambdas and function bindings:

auto func = [](int size, auto& str){ 
    NormalizePath(str, GetParsedPathLength(str), size); 
};

Then call the function with ranges::for_each:

std::ranges::for_each(
    warnings, std::bind_front(func, longestPathLength), &warning::path
);

Demo

  • Related