Есть ли случай, когда это будет действительный код на C++?Применить оператор приращения к функции
int main()
{
int k = 0;
++f(k);
}
Есть ли случай, когда это будет действительный код на C++?Применить оператор приращения к функции
int main()
{
int k = 0;
++f(k);
}
Да, если f
возвращает ссылку.
int main()
{
int k = 0;
++f(k);
}
int & f(int & k) {
return k;
}
Edit:
Как было отмечено в комментариях, есть другая возможность: вы можете позвонить ++f(k)
, если f
возвращает тип класса и имеет ++operator(void)
перегруженный как функции члена.
Ну, например, он будет работать, если вы предшествуют этот код с:
#define f
но не применяя оператор приращения к функции, как вы, кажется, желание в заголовке , Если попытаться применить его к функции, как показано ниже:
int f (int x) { return x + 1; }
вы получите сообщение об ошибке:
error: lvalue required as increment operand
, потому что возвращаемое значение не является lvalue
(очевидно). Вы можете возвращают ссылку на переменную, которая затем может быть увеличен таким образом:
#include <iostream>
int xyzzy = 42;
int & f(int x) { return xyzzy; }
int main() {
int k = 0;
++f(k);
std::cout << xyzzy << '\n';
return 0;
}
Это работает, потому что возвращенная ссылка ссылки на переменную xyzzy
; он выводит:
43
f()
может возвращать ссылку, которую вы хотите увеличить после возвращения из функции. например:
int someGlobal;
int& f(int k) {
return someGlobal;
}
Хотя это неправильно во многих отношениях [designically говоря]
Когда е возвращает Int &, например.
@delnan: 'int &' * is * lvalue. – celtschk
@celtschk Я почти уверен, что ответ использовался, чтобы сказать 'int', и кажется, что хотя бы один человек согласился (мой комментарий +1, и ответ имел обыкновение иметь downvote). В любом случае, удалите его сейчас. – delnan
@ delnan: Я думал об этой возможности, но SO не отображал редактирования ответа (и до сих пор этого не делает). Может ли исчезнуть редактирование? – celtschk
В очевидном случае, если f
имеет подпись int f(int)
или какой-либо эквивалент, нет: вы не можете использовать ++
на временном. Он даже не компилируется.
Если это сделано, чтобы скомпилировать какой-либо другой трюк (например, f
, возвращающий ссылку), тогда все еще остается вопрос, что такой код является примером того, чего следует избегать.
Итак, все зависит от того, что вы имеете в виду под номером , действительным: оно может быть действительным в качестве компилятора, но IMO недействительно в том смысле, что я мог читать этот код и не иметь некоторых вещей, которые можно сказать о Автор.
Да, по-моему, я имею в виду компиляцию. – PetrosB
Функция f
будет запущена перед предварительным оператором ++. Это связано с precedence of operators. Вы не увеличиваете функцию, а возвращаете значение. Таким образом, этот код будет действителен только в том случае, если значение, возвращаемое f(k)
, может быть увеличено.
Короче говоря, да, этот код действителен во многих случаях (когда объект f возвращается не const и может быть увеличен).
Sure: Предположим, вы хотите один больше, чем квадратный номер:
int & square(int & n)
{
n = n * n;
return n;
}
Теперь вы можете сказать,
int k;
++f(k);
и имеет тот же эффект, как int k = 0 * 0 + 1;
. Пример не так увлекателен для 0
, но имеет смысл вообще. Не вызывает сомнений, является ли хороший стиль функцией как мутировать аргумент, так и возвращать ссылку на него, но предварительный инкремент имеет одинаковую семантику, и вы можете написать ++square(++square(k))
, если хотите.
Кроме того, если 'f' возвращает объект типа класса с перегруженным' operator ++ '. Перегрузка является функцией-членом, и вы * можете * вызывать функцию-член на _rvalue_. –
@MikeSeymour: спасибо, что указали это, я попробовал это с помощью int, и он не работал, но не пробовал с типом класса. Моя вина. – jupp0r
Действительно, он не будет работать для типов, отличных от класса; встроенный оператор может быть применен только к _lvalue_, а функции-члены также могут быть вызваны на _rvalue_. –