Какова точка consterpr end istream (дозорный) итератор?

N2976 предложил добавить constexpr к некоторым местам стандартной библиотеки. Он отмечает, что iostream не подходит для концевых итераторов constexpr EXCEPT. Таким образом, istream_iterator и istreambuf_iterator были предоставлены constexpr конструкторы по умолчанию, и об этом. Например, вы можете увидеть в libstdС++), который constexpr появляется только один раз во всем файле. LWG, вызвавший это изменение, был # 1129. В нем говорится:

istream_iterator и istreambuf_iterator должны поддерживать литерал дозорных значений. Конструктор по умолчанию часто используется для и может легко быть буквальным значением для istreambuf_iterator и istream_iterator, когда значение итерации типы. [Rest omitted]

Это не имеет для меня большого смысла. Может ли кто-нибудь показать мне пример того, что они означают?

N3308 - это еще один документ, который упоминает, но не объясняет проблему:

Некоторые из конструкторов istream_iterator<T> должны быть constexpr, если T является литералом типа. Цель состоит в том, чтобы разрешить существующая технология реализации хранения типа T inline to продолжают работать. [libstdС++ делает это, _Tp _M_value] Однако, это фактически исключает эту технику: конструкторы по умолчанию и копии из T не нужно отмечать constexpr, а если нет, то Конструкторы istream_iterator<T> не могли быть constexpr.

Приведенный выше объясняет тривиальный конструктор копирования и деструктор, но не почему конструктор по умолчанию отмечен как constexpr.

Кроме того, тестирование на онлайн GCC 5.2.0, я скопировал реализацию libstdС++. Единственное изменение - удалить constexpr из istream_iterator(). В обоих случаях сборки идентичны.

С constexpr

Без constexpr

Ответ 1

Пример итератора конца конца потока, используемого как контрольное значение, находится здесь:

// 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/

Объявление этого параметра constexpr позволяет компилятору сбрасывать вызовы, которые создают итераторы конца потока, в константы, а не вызывать функцию каждый раз. В противном случае это могло бы быть сделано на каждой итерации цикла.