The following is the code:
#include <vector>
#include <string>
std::vector<std::string> zip(
const std::vector<std::string> & a,
const std::vector<std::string> & b) {
std::vector<std::string> result;
for (int i = 0; ; ++i) {
bool a_indexable = i < static_cast<int>(a.size()); //I couldn't get what the following two lines mean as I asked in the title, I couldn't get what bool means here and I couldn't get what i < static_cast<int>(a.size()) means here
bool b_indexable = i < static_cast<int>(b.size());
if (!a_indexable && !b_indexable) {
break;
}
std::string element;
if (a_indexable) {
element += a[i];
}
if (b_indexable) {
element += b[i];
}
result.push_back(element);
}
return result;
}
I know what static_cast<int>
means in the code but I feel confused about its combination especially like i < static_cast<int>(b.size())
. Please explain it if you could help me.
a_indexable
is a boolean that indicates if i
is a valid index for the vector a
.
A naive way of computing a_indexable
would be:
bool a_indexable = i < a.size();
However a.size()
is of type std::size_t
which is an unsigned integer. Mixing signed with unsigned integers is troublesome so most compilers will emit a warning for i < a.size()
. The solution is to explicitly cast a.size()
to the type of i
like in your example:
bool a_indexable = i < static_cast<int>(a.size());
a.size()
and b.size()
here refers to std::vector::size()
. std::vector::size()
returns a size_t
(usually an unsigned int
), not an int
.
As you can see in this question , comparing an int
to an size_t
will give a warning. By static_cast
ing to an int, whoever wrote this code is getting rid of a warning from the compiler.
It's actually a way of deciding whether a given index is valid for the vector and therefore ensuring you don't try to read beyond the end of a vector. If the index is less than the size, then it's valid. The cast avoids warnings form mixing signed and unsigned values in the comparison.
However, I probably would have just made i
a size_t
type so that such casting was unnecessary, especially since i
is very limited in scope.
In fact, I would have written it differently so as to avoid that sort of logic altogether, by getting the common length up front (the minimum of both lengths) and then processing it in sections, something like (with some type aliasing goodness to make the code a little mode readable, and as a complete program showing a minimal test harness):
#include <vector>
#include <string>
using vecString = std::vector<std::string>;
vecString zip(const vecString &a, const vecString &b) {
vecString result;
auto asz = a.size();
auto bsz = b.size();
auto common_sz = std::min(asz, bsz);
// Handle common size, both vectors are guaranteed
// to have elements at these indices.
for (size_t i = 0; i < common_sz; ++i)
result.push_back(a[i] + b[i]);
// Handle where sizes differ, only ONE of these loop
// bodies will be executed, depending on which is
// larger. Of course, if sizes were identical,
// neither loop body will execute.
for (size_t i = common_sz; i < asz; ++i)
result.push_back(a[i]);
for (size_t i = common_sz; i < bsz; ++i)
result.push_back(b[i]);
return result;
}
#include <iostream>
int main() {
std::vector<std::string> vec1, vec2;
vec1.push_back("pax");
vec1.push_back("is");
vec1.push_back("clever");
vec2.push_back("diablo");
auto zipVec = zip(vec1, vec2);
for (const auto &zipString: zipVec)
std::cout << zipString << '\n';
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.