简体   繁体   中英

What does "bool a_indexable = i < static_cast<int>(a.size())" mean in the following code?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM