06 当auto推导出非预期类型时应当使用显式的类型初始化
06 当auto推导出非预期类型时应当使用显式的类型初始化
1. auto推导出非预期类型
有时候 auto 的类型推导会和你想的南辕北辙。举一个例子,假设我有一个函数接受一个 Widget 返回一个 std::vector<bool> ,其中每个 bool 表征 Widget 是否接受一个特定的特性:
std::vector<bool> features(const Widget& w); |
假设要取第5个bool:
Widget w; |
这份代码没有任何问题。它工作正常。但是如果我们做一个看起来无伤大雅的修改,把 highPriority 的显式的类型换成 auto :
auto highPriority = features(w)[5]; |
正如注释中所提到的,调用 processWidget 现在会导致未定义的行为。但是为什么呢?答案是:在使用 auto 的代码中,highPriority 的类型已经不是 bool 了。
尽管 std::vector<bool> 从概念上说是 bool 的容器,对 std::vector<bool> 的 operator[] 运算符并不一定是返回容器中的元素的引用( std::vector::operator[] 对所有的类型都返回引用,就是除了 bool )。
事实上,他返回的是一个 std::vector<bool>::reference 对象(一个在 std::vector<bool> 中内嵌的class)。
2. 显式的类型初始化原则
不管你是如何发现它们,一旦 auto 被决定作为推导代理类的类型而不是它被代理的类型,它就不需要涉及到关于 auto , auto 自己本身没有问题。问题在于 auto 推导的类型不是所想让它推导出来的类型。
解决方案就是强制一个不同的类型推导。 我把这种方法叫做显式的类型初始化原则。 显式的类型初始化原则涉及到使用 auto 声明一个变量,但是转换初始化表达式到 auto 想要 的类型。下面就是一个强制 highPriority 类型是 bool 的例子:
auto highPriority = static_cast<bool>(features(w)[5]); |
发布于