Почему (void) между двумя разделенными запятыми операторами в цикле for
Следующий код приведен из примера реализации std::lexicographical_compare
на cppreference.com:
template<class InputIt1, class InputIt2>
bool lexicographical_compare(InputIt1 first1, InputIt1 last1,
InputIt2 first2, InputIt2 last2)
{
for ( ; (first1 != last1) && (first2 != last2); ++first1, (void) ++first2 ) {
if (*first1 < *first2) return true;
if (*first2 < *first1) return false;
}
return (first1 == last1) && (first2 != last2);
}
Почему существует цикл (void)
в цикле и что было бы следствием не помещать его там?
Ответы
Ответ 1
Если тип значения, возвращаемого оператором приращения префикса типа InputIt1
, имеет перегруженный оператор запятой, тогда выражение ++first1, ++first2
может вызывать его, поэтому результат каста от ++first2
до void
гарантирует, что никакой перегруженный оператор запятой не будет вызывается, поскольку перегруженный оператор запятой не может принять void
в качестве параметра.
Ответ 2
Кажется, это параноидальный реализатор, охватывающий их базы, потому что они не знают точных деталей типов, с которыми они имеют дело.
Вы можете или не знать, что operator ,
может быть перегружен для типов. Из-за этого могут возникнуть непреднамеренные последствия при использовании выражения типа ++first1, ++first2
или даже просто first1, first2
.
Приведение (void)
помещается туда, так что любой перегруженный operator ,
не может вступить в силу, поскольку операторы не могут работать с неполным типом void
.