Понимание того, что делает (void) при размещении перед вызовом функции

Мои вопросы:

Почему (void) отвечает за возврат 9X_cxx другого значения? Что именно происходит?

struct S {
  int operator,(int) { return 0; }
};
std::cout << (S(), 42) << '\n';           // prints '0'
std::cout << ((void) S(), 42) << '\n';    // prints '42'

11
0
3
Общее количество ответов: 3

Ответ #1

Ответ на вопрос: Понимание того, что делает (void) при размещении перед вызовом функции

Проблема в том, что оператор запятой был 9X_cxx перегружен.

Итак, первая строка:

(S(), 42)

Будет вызывать 9X_c++ эту пользовательскую перегрузку оператора 9X_c++ запятой, поскольку аргументы S и int соответствуют 9X_cxx этой перегрузке. Обратите внимание, что 9X_cpp эта версия всегда возвращает значение 0.

Во 9X_cpp второй строке:

((void) S(), 42)

Ваша пользовательская перегрузка 9X_cxx оператора запятой не соответствует переданному 9X_cpp типу, поскольку первый аргумент имеет тип 9X_cpp void (приведение выполнено). Итак, срабатывает 9X_c++ build-in version of comma operator. Это означает, что будет возвращен второй 9X_c++ аргумент. Именно поэтому во второй строке 9X_cxx печатается 42.

Примечание:

  • Да C++ позволяет перегружать оператор запятой, но это необычно и довольно часто считается плохой практикой. Во многих стандартах кодирования это запрещено.

22
0

Ответ #2

Ответ на вопрос: Понимание того, что делает (void) при размещении перед вызовом функции

(void) исполняет explicit conversion (до void).

Для первого случая S(), 42, S::operator, будет 9X_cpp вызываться для временного S (т.е. S()) и возвращать 9X_cpp значение 0.

Во втором случае временный S явно 9X_cpp преобразуется в void, поэтому для (void) S(), 42 вместо него 9X_cxx будет вызываться built-in comma operator, в результате чего 2-й 9X_c++ операнд 42 будет возвращен оператором запятой, а 9X_c++ затем распечатанный. (Первый операнд (void) S() оценивается 9X_cpp первым, и результат отбрасывается.)

Тип, значение 9X_cpp и категория значения результата выражения 9X_cpp с запятой точно такие же, как тип, значение 9X_cpp и категория значения второго операнда

18
0

Ответ #3

Ответ на вопрос: Понимание того, что делает (void) при размещении перед вызовом функции

Важно отметить во втором утверждении, что 9X_c++ приведение имеет более высокий приоритет по сравнению с оператором 9X_cpp запятой ,. Это означает, что выражение ((void) S(), 42) на 9X_cpp самом деле сгруппировано как (или эквивалентно 9X_cxx записи) (((void) S()), 42) из-за operator precedence.

Таким образом, во втором 9X_c++ случае временное S() сначала приводится к void, так 9X_c++ что в результате получается void. Теперь, поскольку 9X_cpp пользовательский перегруженный S::operator,(int) более нежизнеспособен(поскольку 9X_cpp он принимает аргументы типа S и int), встроенный 9X_cxx operator, будет использоваться с операндами типа 9X_cxx void(это было возвращается из случая, который 9X_c++ вы использовали) и 42, и он вернет самый правый 9X_cpp операнд 42. Следовательно, второе выражение 9X_cpp выводит 42.

14
0