Что делает оператор запятой? - PullRequest
       47

Что делает оператор запятой?

40 голосов
/ 29 сентября 2008

Что делает следующий код в C / C ++?

if (blah(), 5) {
    //do something
}

Ответы [ 8 ]

66 голосов
/ 29 сентября 2008

Оператор запятой применяется, а значение 5 используется для определения условного истина / ложь.

Он выполнит blah () и вернет что-то (предположительно), затем будет использован оператор запятой, и единственное, что будет использовано для определения значения true / false для выражения, будет 5.


Обратите внимание, что оператор, может быть перегружен для возвращаемого типа функции blah () (которая не была указана), что делает результат неочевидным.

45 голосов
/ 29 сентября 2008

Если оператор запятой не перегружен, код выглядит следующим образом:

blah();
if (5) {
  // do something
}

Если оператор запятой перегружен, результат будет основан на этой функции.

#include <iostream>
#include <string>

using namespace std;

string blah()
{
    return "blah";
}

bool operator,(const string& key, const int& val) {
    return false;
}

int main (int argc, char * const argv[]) {

    if (blah(), 5) {
        cout << "if block";
    } else {
        cout << "else block";
    }

    return 0;
}

(отредактировано, чтобы показать сценарий перегрузки оператора запятой. Спасибо Дэвиду Пьеру за комментарий)

20 голосов
/ 29 сентября 2008

Я знаю одну вещь, которую должен делать этот вид кода: он должен вызвать увольнение кодера. Я бы немного боялся работать рядом с тем, кто пишет так.

13 голосов
/ 29 сентября 2008

В патологическом случае это зависит от того, что делает оператор запятой ...

class PlaceHolder
{
};

PlaceHolder Blah() { return PlaceHolder(); }

bool operator,(PlaceHolder, int) { return false; }

if (Blah(), 5)
{
    cout << "This will never run.";
}
1 голос
/ 30 сентября 2008

На более широкий ответ. Оператор запятой (не перегруженный) разрешается как, выполняет первую часть и возвращает вторую часть.

Так что если у вас есть (foo (), bar ()), обе функции будут выполнены, но значение выражения оценивается как bar () (и тип выражения также).

Хотя я не буду говорить, что для этого есть справедливые способы использования, обычно считается, что код трудно читать. Главным образом потому, что не многие языки разделяют такие конструкции. Так что, как личное правило, я избегаю этого, если я не добавляю код в ранее существующее выражение и не хочу полностью изменять его формат.

Пример: у меня есть макрос (не обсуждаю, следует ли вам использовать макросы или нет, иногда это даже не вы написали)

FIND_SOMETHING (X) (x> 2)? find_fruits (x): find_houses (x)

И я обычно использую его в назначениях, таких как my_possession = FIND_SOMETHING (34);

Теперь я хочу добавить в него журнал для целей отладки, но я не могу изменить функции поиска. Я мог бы сделать:

FIND_SOMETHING (X) (x> 2)? (LOG («в поисках фруктов»), find_fruits (x)) :( LOG («в поисках домов»), find_houses (x))

1 голос
/ 29 сентября 2008

Я бы сказал, что это зависит от бла ().

0 голосов
/ 01 октября 2008

Иногда я использую подобные конструкции для отладки. Когда я заставляю значение if близко к истине, независимо от возвращаемого значения бла. Очевидно, что он никогда не должен появляться в рабочем коде.

0 голосов
/ 29 сентября 2008

Следующее было написано, предполагая, что это код C, либо в файле C, либо в блоке C файла C ++:

Это бессмысленно , если . Он вызовет blah (), однако результат blah () не учитывается , если вообще. Единственное, что рассматривается, это 5, поэтому if всегда будет принимать значение true. IOW вы могли бы написать этот код как

blah();
// do something

без каких-либо , если вообще.

...