【问题标题】:What does "bool a_indexable = i < static_cast<int>(a.size())" mean in the following code?以下代码中的“bool a_indexable = i < static_cast<int>(a.size())”是什么意思?
【发布时间】:2020-08-29 23:22:02
【问题描述】:

以下是代码:

#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;
}

我知道static_cast&lt;int&gt; 在代码中的含义,但我对它的组合感到困惑,尤其是i &lt; static_cast&lt;int&gt;(b.size())。如果你能帮助我,请解释一下。

【问题讨论】:

  • for (int i = 0; ; ++i) 应该是for (std::size_t i = 0; ; ++i)

标签: c++ c++17


【解决方案1】:

a_indexable 是一个布尔值,指示 i 是否是向量 a 的有效索引。

计算a_indexable 的简单方法是:

bool a_indexable = i < a.size();

但是a.size()std::size_t 类型,它是一个无符号整数。将有符号整数与无符号整数混合很麻烦,因此大多数编译器都会针对i &lt; a.size() 发出警告。解决方案是将a.size() 显式转换为i 的类型,如您的示例中所示:

bool a_indexable = i < static_cast<int>(a.size());

【讨论】:

  • 不确定如果.size() 大于std::numeric_limits&lt;int&gt;::max(),演员会做什么,但这可能不太好。大多数实用程序不会有这个问题。
  • i 设为size_t 变量可能会更好。
【解决方案2】:

a.size()b.size() 这里指的是std::vector::size()std::vector::size() 返回 size_t(通常是 unsigned int),而不是 int

正如您在this question 中看到的,将intsize_t 进行比较会发出警告。通过 static_casting 到 int,编写此代码的人正在摆脱来自编译器的警告。

【讨论】:

  • 实际上它会返回一个size_t,在指针大于int的系统上它会大于unsigned int
  • @MarkRansom 已更正。谢谢。
【解决方案3】:

这实际上是一种确定给定索引是否对向量有效的方法,从而确保您不会尝试读取超出向量末尾的内容。如果索引小于大小,那么它是有效的。强制转换避免了在比较中混合有符号和无符号值的警告。

但是,我可能只是将 i 设置为 size_t 类型,这样就没有必要进行这种转换,尤其是因为 i 的范围非常有限。


事实上,我会以不同的方式编写它,以便完全避免这种逻辑,方法是预先获取公共长度(两个长度的最小值),然后分段处理,类似的东西(具有某种类型的别名优势,使代码具有一点模式可读性,并且作为一个完整的程序显示了一个最小的测试工具):

#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';
}

【讨论】:

    猜你喜欢
    • 2014-05-09
    • 1970-01-01
    • 2017-05-10
    • 1970-01-01
    • 2014-11-02
    • 2015-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多