The following C function is extracted from lines 151 - 157 here:
template <typename... T>
std::string JoinPaths(T const&... paths) {
boost::filesystem::path result;
int unpack[]{0, (result = result / boost::filesystem::path(paths), 0)...};
static_cast<void>(unpack);
return result.string();
}
The function JoinPaths("foo", "bar", "doo.txt")
will return a std::string
with value "foo/bar/doo.txt"
(I think) so I understand the semantics of the function.
I am trying to understand the two lines before the return
statement. unpack
in an array of int
s, but what (and why) is happening with the leading 0's and the ellipses at the end. Can someone explain how this gets expanded? Why the 0's? I assume the static_cast
is there to keep the compiler from optimizing away the array?
CodePudding user response:
As already noted while I was typing this up, it is a pre-C 17 method to perform a fold expression.
It uses a local temporary array of int, along with the comma operator, to sneak a bunch of what would otherwise be:
result = result / paths[n]
into an integer expression, ultimately producing:
int unpack[]{
0,
(result = result / paths[0], 0),
(result = result / paths[1], 0),
...,
(result = result / paths[N], 0)
};
These days, the following will do:
template <typename...Pathnames>
std::string JoinPaths( Pathnames...pathnames )
{
return (std::filesystem::path( pathnames ) / ...).string();
}
CodePudding user response:
int unpack[]{0, (result = result / boost::filesystem::path(paths), 0)...};
The first 0
is there to not try to create an empty array if someone calls the function with zero arguments.
(result = result / boost::filesystem::path(paths), 0)
This evaluates result = result / boost::filesystem::path(paths)
and discards it. The result is the 0
to the right side of the comma.
...
"unfolds" the expression (which is a fold expression), putting a ,
between each, making it into:
int unpack[]{0, (result = result / boost::filesystem::path("foo"),0),
(result = result / boost::filesystem::path("bar"),0),
(result = result / boost::filesystem::path("doo.txt"),0)
};
So, there will be four 0
:s in unpack
. The cast afterwards is just to disable the warning about the unused variable unpack
.
[[maybe_unused]] int unpack ...
could have been used instead to remove the warning in modern C .