Информация об изменениях

Сообщение Re[10]: хитрая конструкция от 06.03.2015 19:21

Изменено 07.03.2015 11:23 Кодт

Здравствуйте, Hard_Club, Вы писали:

H_C>Как эта штука — #define CALL(expr) ( (expr), void(), 0 ) — называется в стандарте?


Comma operator
Неявно определён над любыми (в т.ч. void) операндами, строго последовательно выполняет их и возвращает значение правого операнда.
Здесь получается такая конструкция
#define COMMA(x,y) (x),(y)
#define CALL(expr)  COMMA( COMMA((expr),void()), 0 )

Первая запятая над expr и void нужна для того, чтобы предотвратить нечаянный выбор перегруженного оператора запятой. (Перегрузить оператор для void-аргумента в принципе невозможно).
Результат имеет тип void, а уже void,int — заведомо — неявно определён компилятором.

Подытоживая,
— f(x) — может быть void или какого-нибудь неудобного для передачи в (...) типа
— f(x),0 — может быть типа с перегруженным operator,(T,int) — получим вместо int неизвестно что
— f(x),void() — получим void, но ничего с ним не сможем сделать
— f(x),void(),0 — получим int
Re[10]: хитрая конструкция
Здравствуйте, Hard_Club, Вы писали:

H_C>Как эта штука — #define CALL(expr) ( (expr), void(), 0 ) — называется в стандарте?


Comma operator
Неявно определён над любыми (в т.ч. void) операндами, строго последовательно выполняет их и возвращает значение правого операнда.
Здесь получается такая конструкция
#define COMMA(x,y) ((x),(y))
#define CALL(expr) COMMA( COMMA((expr),void()), 0 )

Первая запятая над expr и void нужна для того, чтобы предотвратить нечаянный выбор перегруженного оператора запятой. (Перегрузить оператор для void-аргумента в принципе невозможно).
Результат имеет тип void, а уже void,int — заведомо — неявно определён компилятором.

Подытоживая,
— f(x) — может быть void или какого-нибудь неудобного для передачи в (...) типа
— f(x),0 — может быть типа с перегруженным operator,(T,int) — получим вместо int неизвестно что
— f(x),void() — получим void, но ничего с ним не сможем сделать
— f(x),void(),0 — получим int