C++11:初期化子からの型の導出:auto

C++11では、「式」から値の型を導出することができるようになった。

auto x = 式;

初期化子から変数の型を導出できるauto型指定子は、型を書くことが面倒な場合や、正確に知ることが難しい場合に便利だろう。

template<class T>
void print_all(const std::vector<T> &v)
{
    for ( auto i = v.begin(); i != v.end(); ++i ) {
        std::cout << *i << "\n";
    }
}

C++98では、以下のように書く必要があった。

template<class T>
void print_all(const std::vector<T> &v)
{
    for ( typename std::vector<T>::const_iterator i = v.begin(); i != v.end(); ++i ) {
        std::cout << *i << "\n";
    }
}

型がテンプレート引数に強く依存している場合は、auto無しに書くことは難しいだろう。

template<class Tx, class Ty>
auto multiply(const Tx &x, const Ty &y) -> decltype(x * y)
{
    return x * y;
}

戻り値型の後方宣言decltypeについては、後日説明予定。)

導出される型に対して、constや&(参照)などの型指定子や修飾子を付けることもできる。

void func(std::vector<std::string> &v)
{
    for ( const auto &s : v ) { // sはconst std::string &
        // ...
    }
}

なお、autoの古い意味(「これはローカル変数である」)は、今では不正になった。

マイコーディングルール

  • わざわざ型を明示すべき特別な事情が無い限り、autoを用いる。
  • autoで変数を宣言する場合は、=構文を用いる。{}構文を用いると、std::initializer_list<T>型を導いてしまうため。(C++17で変更される)
auto x = 1; // xはint
auto y{1};  // yはintではなくstd::initializer_list<int>(C++17ではint)