EMCPP条款6:当auto推导的型别不符合要求时,使用带显式型别的初始化物习惯用法

YiQi 管理员

有一个函数,接收一个 Widget 并返回一个 std::vector<bool>

1
2
3
4
std::vector<bool> features(const Widget& w);

Widget w;
auto highPriority = features(w)[5];

在这里,highPriority 不会被推导为 bool,而是 std::vector<bool>::reference,这是一个 bool 的“代理类”。如果我们想要 highPrioritybool,那么就要使用 auto 的“显式初始化”语法:

1
bool highPriority = features(w)[5];

这里,features 返回了一个 std::vector<bool>,然后针对该对象执行 operator[],返回了一个 std::vector<bool>::reference,然后将其转换成 bool

一个普遍的规律是, “隐形”代理类和 auto 无法和平共处。

如何识别“隐形”代理类呢?

  • 使用它们的库往往会在文档中写明这一点
  • 查看头文件

auto 本身并不是问题。问题在于 auto 没有推导成为你想推导出来的型别。

针对初始化表达式进行强制型别转换,转换成你想要 auto 推导出来的型别。可以提升代码可续性和意图。

1
2
auto highPriority = static_cast<bool>(features(w)[5]);
auto index = static_cast<int>(d * c.size());

要点速记

  • “隐形”的代理型别 可以导致 auto 根据初始化表达式推导出 “错误的"型别
  • 带显式型别的初始化物习惯用法强制 auto 推导出你想要的型别。
此页目录
EMCPP条款6:当auto推导的型别不符合要求时,使用带显式型别的初始化物习惯用法