Какой смысл использовать constexpr end istream (sentinel) итераторы?

N2976 предложил добавить constexpr в некоторые места в стандартной библиотеке. Отмечает, что iostreamс не подходит для constexpr ЗА ИСКЛЮЧЕНИЕМ конечных итераторов. Так istream_iterator а также istreambuf_iterator были даны constexpr конструкторы по умолчанию, и это все. Например, вы можете увидеть в реализации libstdC++, что constexpr появляется только один раз во всем файле. LWG, которая вызвала это изменение, была # 1129. Это говорит:

istream_iterator а также istreambuf_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

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 позволяет компилятору сворачивать вызовы, которые создают итераторы конца потока в константы, вместо того, чтобы каждый раз вызывать функцию. В противном случае он мог бы делать это на каждой итерации цикла.

Другие вопросы по тегам