首先第一点
auto只能推导 静态型别
也就是编译时期就能确定的型别
所以看到程式中有virtual这个关键字
用auto就要小心了
但原po这个例子没问题
再来回到原PO的问题
Q: 你如何知道你的auto推导出来的是什么型别?
这边提供一个检查技巧/范例
(effective modern c++这本书有)
//先创建一个测试用的class TD
template<typename T> // declaration only for TD;
class TD; // TD == "Type Displayer"
//以auto宣告型别并初始化
auto t = "some string";
//使用TD
TD<decltype(t)> tType;
//这时候你通常会看到类似的编译错误讯息
error: aggregate 'TD<char*> tType' has incomplete type and
cannot be defined
那个 'TD<char*> tType'里面的char*就是你用auto推出来的型别
再看这例子
std::vector<bool> features(const Widget& w);
Widget w;
…
auto highPriority = features(w)[5]; // is w high priority?
…
processWidget(w, highPriority); // process w in accord
// with its priority
你猜highPriority会被推成什么型别? 理想的bool?
不对 它被推成
std::vector<bool>::reference 这个型别
这关系到std::vector<bool>里面的实作方式
这时候只能避开auto了
乖乖使用bool
但可以用上面的方式先检查推导出来的型别
(后面一点的compiler 好像可以正常推导出bool)
补充:
个人最推荐的auto使用情境
template<typename It> // algorithm to dwim ("do what I mean")
void dwim(It b, It e) // for all elements in range from
{
//想自动取得It<T> 里面的型别T作为初始化宣告
T val = ...
}
你有想过我要如何自动得到并初始化
It<T>里面的型别T吗?
答案是要用到trait-class
(没用auto的话)
template<typename It> // algorithm to dwim ("do what I mean")
void dwim(It b, It e) // for all elements in range from
{ // b to e
while (b != e) {
typename
std::iterator_traits<It>::value_type
currValue = *b;
…
}
}
三小?
这么简地的事情
也要弄到那么复杂的trait-class?
C++11自从有了auto之后,
这件事情不再痛苦
这件事情不再痛苦
template<typename It> // as before
void dwim(It b, It e)
{
while (b != e) {
auto currValue = *b;
…
}
参考:
Effective Modern C++ item5 与 item6
<大推这本书>