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

どれを使うべきか

  1. 基本的には全部 auto&& で構いません

    const でも非const でも lvalue でも rvalue でも何でも受け取れます



  2. const を明示したいなら const auto& を使います

    const であれば lvalue でも rvalue でも受け取れます



  3. コピーしてほしくない場合で rvalue参照が不要なことが明らかな場合は auto& でも構いません

    lvalue であれば const でも非const でも受け取れます



  4. 明らかにコピーが必要なときだけ auto を使います

    また読み込み用の整数やポインタやイテレータなど const参照にする意味がないようなものは auto でも構いません

auto の仕組み

テンプレート引数に適用される reference collapsing は auto にも適用されます
auto の型推論は template argument deduction と同じ仕組みです

C++ の内部的には auto は template の一種のようなものなのです
auto の実体が何であるかを考えるときはそこに指定されているものがテンプレートに渡されていると考えるといいでしょう