最終更新日時(UTC):
が更新

履歴 編集

範囲for文がカスタマイゼーションポイントを見つけるルールを緩和(C++20)

概要

C++17までは、範囲for文に指定するシーケンスの型がbegin()end()メンバ関数のどちらかでも持っていればそれを使用し、どちらも持っていなければADLで非メンバ関数のbegin()end()を探索する仕様となっていた。

C++20ではこのルールを緩和し、begin()/end()メンバ関数の両方があればそれを使用し、どちらかが不足していれば非メンバ関数のbegin()/end()を探しにいくよう改定する。

これは、beginもしくはendという何らかのメンバ (関数、変数、型) が特殊な意味を持ち、そのメンバが範囲for文で使用することを意図していないような状況に対応するための改訂である。

#include <sstream>
#include <iterator>

struct X : std::stringstream {
  X(const char* s)
    : std::stringstream(s) {}
};

std::istream_iterator<char> begin(X& x)
{
  return std::istream_iterator<char>(x);
}

std::istream_iterator<char> end(X&)
{
  return std::istream_iterator<char>();
}

#include <iostream>
int main()
{
  X x{"Hello"};

  // C++17まではコンパイルエラー
  // (std::stringstream::endメンバだけが見つかり、対応するbeginがないというエラーになる)。
  // C++20ではOK
  for (char c : x) {
    std::cout << c << std::endl;
  }
}

出力

H
e
l
l
o

関連項目

参照