for (; 0 < _Count; --_Count, (void)++_Dest, ++_First)
Вообще не понятно ...
----
Может это типа новое слово в подсказках оптимизатору компилятора?
То есть, мы как бы говорим, что нам не интересен результат оператора ++ и соответствующий (процессорный) код ( return *this; ) можно не генерировать?
Это единственное объяснение, которое пришло в мне в голову
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re: "for(...;...; ..., (void)++_First)" - в чем замысел (voi
Защита от переопределения operator,.
Если этот оператор задан, то запись ++_Dest, ++_First может означать (++Dest).operator,(++_First), то есть делать совсем не то, что было задумано.
А так как оператор запятая не может принимать одним из своих аргументов void, то в конструкции ++_Dest, (void)++_First он никогда не вызовется.
watchmaker:
W>А так как оператор запятая не может принимать одним из своих аргументов void, то в конструкции ++_Dest, (void)++_First он никогда не вызовется.
Если подходить к вопросу совсем уж педантично, то надо оба операнда приводить к void. Когда хотя бы один из операндов запятой имеет пользовательский тип, перегруженные запятые рассматриваются, даже если другой операнд имеет тип void. Конечно, ни один из кандидатов не пройдёт как минимум из-за несоответствия критерию "viable function", однако до отсева по этому критерию дело может просто не дойти из-за появления ошибки, ставящей крест на успешной компиляции.
template <class T>
struct A
{
typedef typename T::value_type type;
};
struct X
{
template <class T>
typename A<T>::type operator ,(T const &);
};
struct Y
{
template <class T>
friend typename A<T>::type operator ,(T const &, Y const &);
};
int main()
{
void(), X(); // OK
X(), void(); // error: instantiation of A<void> produces invalid construct void::value_typevoid(), Y(); // error: instantiation of A<void> produces invalid construct void::value_type
}
Здесь выражение X(), void() приведёт к инстанцированию объявления функции typename A<void>::type X::operator ,(void const &), что, в свою очередь, приведёт к инстанцированию определения класса A<void>, где мы получаем void::value_type. Конструкция void::value_type не относится к immediate context объявления typename A<void>::type X::operator ,(void const &), поэтому SFINAE тут не сработает и это будет фатальной ошибкой компиляции.
Аналогично с void(), Y() — этот случай я привёл просто ради симметрии.
Re[2]: "for(...;...; ..., (void)++_First)" - в чем замысел (voi
Здравствуйте, watchmaker, Вы писали:
W>Защита от переопределения operator,. W>Если этот оператор задан, то запись ++_Dest, ++_First может означать (++Dest).operator,(++_First), то есть делать совсем не то, что было задумано. W>А так как оператор запятая не может принимать одним из своих аргументов void, то в конструкции ++_Dest, (void)++_First он никогда не вызовется.
Спасибо, задумался. Сходил на cppreference. Там мне больше понравился другой вид записи этого же выражения: a,void(),b
Мне кажется эта запись более понятна, чем с приведением к типу void и более ясно говорит о целях этой записи.
Цитата:
The comma operator, operator,. Unlike the built-in version, the overloads do not sequence their left operand before the right one. (until C++17) Because this operator may be overloaded, generic libraries use expressions such as a,void(),b instead of a,b to sequence execution of expressions of user-defined types.
Re[2]: "for(...;...; ..., (void)++_First)" - в чем замысел (voi
Здравствуйте, watchmaker, Вы писали:
W>Защита от переопределения operator,.
Мне вот интересно, кто в здравом уме будет перегружать запятую для итератора.
С учётом того, что итератор, скорее всего, будет использовать не только в супер-обобщенной реализации STL, но и в обычном прикладном коде, в котором запятую используют не задумываясь.
Русский военный корабль идёт ко дну!
Re[3]: "for(...;...; ..., (void)++_First)" - в чем замысел (voi
Alexander G:
AG>Мне вот интересно, кто в здравом уме будет перегружать запятую для итератора.
Возможно, кто-нибудь захочет запись диапазонов в виде (i, j) с проверкой их корректности в дебаг-сборке. Тогда выражение вроде ++i, ++j может выплюнуть assertion failure из-за того, что данная пара итераторов не образует допустимый диапазон. Автору шаблона, вероятно, проще сделать void(++i), void(++j), чем потом разбираться с баг-репортами на этот счёт (формально обоснованными, кстати, если требование не перегружать запятую таким образом нигде в предусловиях не оговорено).