10

N2976constexprは、標準ライブラリのいくつかの場所に追加することを提案しました。s はEXCEPT 終了イテレータiostreamには不適切であることに注意してください。constexprそれでistream_iterator、デフォルトのコンストラクタistreambuf_iteratorが与えられました。それはそれについてです。constexprたとえば、ファイル全体で 1 回だけ表示されるlibstdc++ 実装で確認できます。constexprこの変更のきっかけとなった LWG は#1129でした。それは言います:

istream_iteratoristreambuf_iteratorリテラルのセンチネル値をサポートする必要があります。デフォルトのコンストラクターは、範囲を終了するために頻繁に使用され、値の型を反復するときにistreambuf_iterator、のリテラル値になりがち です。istream_iterator【残り略】

これは私にはあまり意味がありません。誰かが彼らの意味の例を見せてもらえますか?

N3308は、この問題について言及しているが説明していない別の論文です。

がリテラル型であるistream_iterator<T>必要が あるコンストラクターconstexprもあります。Tその意図は、インラインのタイプを格納する既存の実装手法がT引き続き機能するようにすることです。[libstdc++ はこれを行う_Tp _M_value] ただし、実際にはこの手法を除外しています。 のデフォルト コンストラクターとコピー コンストラクターをTマークする必要はありconstexprませ istream_iterator<T>constexpr

上記は自明なコピー コンストラクターとデストラクタを説明していますが、既定のコンストラクターが constexpr とマークされている理由は説明していません。

さらに、オンライン GCC 5.2.0 でテストして、libstdc++ の実装をコピーしました。唯一の変更点は、constexpr を から削除したことistream_iterator()です。どちらの場合も、アセンブリは同じです。

constexpr を使用

constexpr なし

4

1 に答える 1

3

センティネル値として使用されるストリーム イテレータの終了の例を次に示します。

// istream_iterator example
#include <iostream>     // std::cin, std::cout
#include <iterator>     // std::istream_iterator

int main () {
  double value1, value2;
  std::cout << "Please, insert two values: ";

  std::istream_iterator<double> eos;              // end-of-stream iterator
  std::istream_iterator<double> iit (std::cin);   // stdin iterator

  if (iit!=eos) value1=*iit;

  ++iit;
  if (iit!=eos) value2=*iit;

  std::cout << value1 << "*" << value2 << "=" << (value1*value2) << '\n';

  return 0;
}

http://www.cplusplus.com/reference/iterator/istream_iterator/istream_iterator/

これを a と宣言constexprすると、コンパイラは毎回関数を呼び出すのではなく、ストリームの終わりの反復子を作成する呼び出しを定数に折りたたむことができます。それ以外の場合は、ループの反復ごとにそうする必要がある場合があります。

于 2015-09-19T08:20:47.723 に答える