Понимание того, что делает (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'
Ответ #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++ позволяет перегружать оператор запятой, но это необычно и довольно часто считается плохой практикой. Во многих стандартах кодирования это запрещено.
Ответ #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 и категория значения второго операнда
Ответ #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
.
-
11
-
3
-
8
-
25
-
4
-
8
-
9
-
11
-
7
-
8
-
4
-
27
-
13
-
3
-
7
-
16
-
18
-
24
-
7
-
7
-
5
-
10
-
29
-
7
-
40
-
8
-
12
-
7
-
20
-
6
-
2
-
7
-
5
-
8
-
12
-
6
-
10
-
5
-
11
-
10
-
7
-
5
-
11
-
3
-
12
-
11
-
6
-
4
-
4
-
7