C++ 11 auto の使い方
はじめに
C++ 11 で auto キーワードが型推論機能として生まれ変わりました
7 Declarations 7.1 Specifiers 7.1.6 Type specifiers 7.1.6.4 auto specifier
ここでは auto の4つの使い方について簡単に説明します
auto, auto&, const auto&, auto&&
(auto* などともできますがここでは省きます)
auto
auto はコピーされても構わないときに使います
整数やポインタなどを受け取る場合はいいのですが、次のような使い方では無駄なコピーが生じてしまうので注意が必要です
s は foo[n] のコピーです
std::vector<std::string> foo; ... for( auto s : foo ){ ... }
auto&
auto& はほぼ万能型です
lvalue であれば const でも非const でも受け取れます
参照なのでコピーは作りません
auto& は lvalue参照がほしい場合に使います
元が非constオブジェクトであれば auto& は非const参照になり、
元が constオブジェクトであれば auto& は const参照になります
foo が非const のとき s は foo[n] の非const参照です
std::vector<std::string> foo; ... for( auto& s : foo ){ s = "..."; }
foo が const のとき s は foo[n] の const参照です
( const std::vector<std::string>& foo ){ ... for( auto& s : foo ){ ; }
const auto&
const auto& は const であれば lvalue でも rvalue でも受け取れます
参照なのでコピーは作りません
読み込み専用の参照がほしい場合に使います
s は foo[n] の const参照です
std::vector<std::string> foo; ... for( const auto& s : foo ){ s = "..."; // error }
auto&&
auto&& は万能型です
参照なのでコピーは作りません
auto&& は元が constか非constか lvalueか rvalueかといったことを気にせず何にでも使える万能型です
foo が何でも受け取れてコピーは作らない
for( auto&& s : foo ){ ... }
※ auto&& の && は reference collapsing が働くことを意味しているものです
rvalue参照の && と同じ記号ですが別のものです
auto&& は rvalue参照であることを意味しているわけではありません
reference collapsing について詳しくはこちらのページにあります
→ C++ 11 の rvalueリファレンスと reference collapsing
どれを使うべきか
- 基本的には全部 auto&& で構いません
const でも非const でも lvalue でも rvalue でも何でも受け取れます
- const を明示したいなら const auto& を使います
const であれば lvalue でも rvalue でも受け取れます
- コピーしてほしくない場合で rvalue参照が不要なことが明らかな場合は auto& でも構いません
lvalue であれば const でも非const でも受け取れます
- 明らかにコピーが必要なときだけ auto を使います
また読み込み用の整数やポインタやイテレータなど const参照にする意味がないようなものは auto でも構いません