2. 今回紹介するItem
• Item 5: Prefer auto to explicit type declarations.
• Item 6: Use the explicitly typed initializer idiom when
auto deduces undesired types.
2015/1/31 2
3. Item 5: Prefer auto to explicit type declarations.
int x;
2015/1/31 3
xが未初期化
明示的な型宣言よりもautoを使おう
auto x; コンパイルエラーにできる
auto x = 0; 初期化を必須にできる
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;
}
}
自明なことを長々と書かねばならなかった
4. Item 5: Prefer auto to explicit type declarations.
int x;
2015/1/31 4
xが未初期化
明示的な型宣言よりもautoを使おう
auto x; コンパイルエラーにできる
auto x = 0; 初期化を必須にできる
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) {
auto currValue = *b;
}
} autoですっきり
5. C++14からはlambda expressionの引数もautoで推論可能
Item 5: Prefer auto to explicit type declarations.
2015/1/31 5
明示的な型宣言よりもautoを使おう
auto derefUPLess = // comparison func.
[](const auto& p1, // for Widgets
const auto& p2) // pointed to by
{ return *p1 < *p2; }; // std::unique_ptrs
lambda expressionもautoで受けることができる
auto derefUPLess = // comparison func.
[](const std::unique_ptr<Widget>& p1, // for Widgets
const std::unique_ptr<Widget>& p2) // pointed to by
{ return *p1 < *p2; }; // std::unique_ptrs
std::functionとの違いは?
9. autoにすることで解決
std::unordered_map<std::string, int>::value_typeは
std::pair<const std::string, int> である
よって、一時オブジェクトが生成されてしまう
Item 5: Prefer auto to explicit type declarations.
2015/1/31 9
明示的な型宣言よりもautoを使おう
std::unordered_map<std::string, int> m;
…
for (const std::pair<std::string, int>& p : m)
{
… // do something with p
}
std::unordered_map<std::string, int> m;
…
for (const auto& p : m)
{
… // do something with p
}
10. Item 5: Prefer auto to explicit type declarations.
2015/1/31 10
Things to Remember
• auto型変数は初期化が必須である。
また、型のミスマッチによる移植性や効率の問題を防ぐことができる。
さらに、リファクタリングを容易にし、
一般的に明示的な型宣言による変数定義に比べて
タイピング量が少なくて済む。
• auto型変数は Item2および6で述べる落とし穴の影響を受ける点に注意
13. Item 6: Use the explicitly typed initializer idiom
when auto deduces undesired types.
2015/1/31 13
autoが期待通りに推論してくれない場合は、
明示的に型付けされた初期化イディオムを使おう
bool highPriority = features(w)[5];
auto highPriority = static_cast<bool>(features(w)[5]);
Matrix sum = m1 + m2 + m3 + m4;
auto sum = static_cast<Matrix>(m1 + m2 + m3 + m4);
右辺でcastすることで、proxy classオブジェクトから実体を取り出す
そこまでしてautoを使うのか??
と考えるならば次のページの例を見てみよう
このように右辺値のcastとautoの組み合わせを、explicitly typed initializer idiomと呼ぶ
14. d は double型で 0.0~1.0の間の値で、indexの先頭からの位置を示すとする
Item 6: Use the explicitly typed initializer idiom
when auto deduces undesired types.
2015/1/31 14
autoが期待通りに推論してくれない場合は、
明示的に型付けされた初期化イディオムを使おう
double calcEpsilon(); // return tolerance value
float ep = calcEpsilon(); // implicitly convert
// double → float
意図してdouble から floatに変換しているのか、ミスか分かりにくい
auto ep = static_cast<float>(calcEpsilon());
int index = d * (c.size() - 1);
auto index = static_cast<int>(d * (c.size() - 1));
こうすれば意図が明確に伝わる
こうすれば意図が明確に伝わる
15. Item 6: Use the explicitly typed initializer idiom
when auto deduces undesired types.
2015/1/31 15
autoが期待通りに推論してくれない場合は、
明示的に型付けされた初期化イディオムを使おう
Things to Remember
• invisibleなproxy型は、auto型の変数で初期化すると、
autoが不適切な型としてdeduceされる。
• explicitly typed initializer idiomを用いることで、autoを期待通りの型として
deduceさせることができる。