2012-02-25 8 views

ответ

4

Да, если f возвращает ссылку.

int main() 
{ 
    int k = 0; 
    ++f(k); 
} 

int & f(int & k) { 
    return k; 
} 

Edit:

Как было отмечено в комментариях, есть другая возможность: вы можете позвонить ++f(k), если f возвращает тип класса и имеет ++operator(void) перегруженный как функции члена.

+0

Кроме того, если 'f' возвращает объект типа класса с перегруженным' operator ++ '. Перегрузка является функцией-членом, и вы * можете * вызывать функцию-член на _rvalue_. –

+0

@MikeSeymour: спасибо, что указали это, я попробовал это с помощью int, и он не работал, но не пробовал с типом класса. Моя вина. – jupp0r

+0

Действительно, он не будет работать для типов, отличных от класса; встроенный оператор может быть применен только к _lvalue_, а функции-члены также могут быть вызваны на _rvalue_. –

3

Ну, например, он будет работать, если вы предшествуют этот код с:

#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 
+0

Любой случай, когда это было бы полезно? – PetrosB

+0

@Petros, предполагая, что вы имеете в виду бит '# define', возможно, нет. Базовый бит, который я мог видеть потенциально полезным, но я уверен, что есть и другие способы сделать это. – paxdiablo

1

f() может возвращать ссылку, которую вы хотите увеличить после возвращения из функции. например:

int someGlobal; 
int& f(int k) { 
return someGlobal; 
} 

Хотя это неправильно во многих отношениях [designically говоря]

0

Когда е возвращает Int &, например.

+0

@delnan: 'int &' * is * lvalue. – celtschk

+0

@celtschk Я почти уверен, что ответ использовался, чтобы сказать 'int', и кажется, что хотя бы один человек согласился (мой комментарий +1, и ответ имел обыкновение иметь downvote). В любом случае, удалите его сейчас. – delnan

+0

@ delnan: Я думал об этой возможности, но SO не отображал редактирования ответа (и до сих пор этого не делает). Может ли исчезнуть редактирование? – celtschk

1

В очевидном случае, если f имеет подпись int f(int) или какой-либо эквивалент, нет: вы не можете использовать ++ на временном. Он даже не компилируется.

Если это сделано, чтобы скомпилировать какой-либо другой трюк (например, f, возвращающий ссылку), тогда все еще остается вопрос, что такой код является примером того, чего следует избегать.

Итак, все зависит от того, что вы имеете в виду под номером , действительным: оно может быть действительным в качестве компилятора, но IMO недействительно в том смысле, что я мог читать этот код и не иметь некоторых вещей, которые можно сказать о Автор.

+0

Да, по-моему, я имею в виду компиляцию. – PetrosB

3

Функция f будет запущена перед предварительным оператором ++. Это связано с precedence of operators. Вы не увеличиваете функцию, а возвращаете значение. Таким образом, этот код будет действителен только в том случае, если значение, возвращаемое f(k), может быть увеличено.

Короче говоря, да, этот код действителен во многих случаях (когда объект f возвращается не const и может быть увеличен).

1

Sure: Предположим, вы хотите один больше, чем квадратный номер:

int & square(int & n) 
{ 
    n = n * n; 
    return n; 
} 

Теперь вы можете сказать,

int k; 
++f(k); 

и имеет тот же эффект, как int k = 0 * 0 + 1;. Пример не так увлекателен для 0, но имеет смысл вообще. Не вызывает сомнений, является ли хороший стиль функцией как мутировать аргумент, так и возвращать ссылку на него, но предварительный инкремент имеет одинаковую семантику, и вы можете написать ++square(++square(k)), если хотите.

Смежные вопросы