Skip to the content.

05 用 auto 替代显式类型声明

int a;   // 潜在的未初始化风险
auto b;  // 错误:必须初始化
template <typename It>
void f(It first, It last) {
  while (first != last) {
    auto val = *first;
    // auto 相当于 typename std::iterator_traits<It>::value_type
  }
}
auto f = [](auto& x, auto& y) { return x < y; };
// std::function 的模板参数中不能使用 auto
std::function<bool(int&, int&)> f = [](auto& x, auto& y) { return x < y; };
std::vector<int> v;
unsigned sz = v.size();  // v.size() 类型实际为 std::vector<int>::size_type
// 在 32 位机器上 std::vector<int>::size_type 与 unsigned 尺寸相同
// 但在 64 位机器上,std::vector<int>::size_type 是 64 位,而 unsigned 是 32 位

std::unordered_map<std::string, int> m;
for (const std::pair<std::string, int>& p : m) {
  // m 元素类型为 std::pair<const std::string, int>
  // 循环中使用的元素类型不一致,需要转换,期间将构造大量临时对象
}

06 auto 推断出非预期类型时,先强制转换出预期类型

std::vector<bool> v{true, false};
for (auto& x : v) {  // 错误:未定义行为
}
std::vector<bool> v{true, false};
bool& p = v[0];  // 错误
bool x = v[0];
auto x = v[0]; // x 类型为 std::vector<bool>::reference
// x 不一定指向 std::vector<bool>的第 0 个 bit,这取决于 std::vector<bool>::reference 的实现
// 一种实现是含有一个指向一个 machine word的指针,word 持有被引用的 bit 和这个 bit 相对 word 的 offset
// 于是 x 持有一个由 opeartor[] 返回的临时的 machine word 的指针和 bit 的 offset
// 这条语句结束后临时对象被析构,于是 x 含有一个空悬指针,导致后续的未定义行为
Matrix sum = m1 + m2 + m3 + m4;
auto x = m1 + m2; // x 可能是 Sum<Matrix, Matrix> 而不是 Matrix 对象
auto x = static_cast<bool>(v[0]);