Re[2]: "for(...;...; ..., (void)++_First)" - в чем замысел (voi
От: N. I.  
Дата: 09.03.17 09:32
Оценка: 98 (6)
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_type
    void(), 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() — этот случай я привёл просто ради симметрии.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.