Определить функцию с #define в cpp?

Я хочу проверить, если несколько раз, я использую #define для этого объявления, я хочу использовать его, но он не работает

#define CHECK_CONDITION(QString condition, start, curr) if(condition == "" ) return true; return (table.commonIn() == "team_id"? list()[start]->team() ==list()[curr]->team() :list()[start]->team() ==list()[curr]->team())

и я использую это так:

if(CHECK_CONDITION(table.commonIn().toStdString(), start, start-idx);) {
   findFalse = true;
}

как я могу использовать это определение в моем коде / спасибо заранее

3 ответа

Решение

Вы можете использовать этот модифицированный макрос:

#define CHECK_CONDITION(condition, start, curr) \
    if(condition == "" || (condition == "team_id"? list()[start]->team() ==list()[curr]->team() :list()[start]->team() ==list()[curr]->team())

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

  • Указание QString для условия

  • Возврат с тех пор не будет иметь логику "возвращаемого значения макроса", но фактически вернется в функцию outter. Это потому, что он должен пройти шаг препроцессора.

  • Вам не нужны отдельные ветви внутри макроса, поскольку это может сделать простое логическое ИЛИ ("||").

  • Вы использовали таблицу, общую в строке get, внутри макроса, даже если вы уже передали условную переменную.

  • Я бы использовал обратную косую черту, чтобы разделить ее на части для лучшей читаемости.

и тогда вы можете сохранить оставшуюся часть кода следующим образом:

if(CHECK_CONDITION(table.commonIn(), start, (start-idx))) {
   findFalse = true;
}

Ошибки здесь вы сделали:

  • У вас была ненужная точка с запятой в условии if, которое является недопустимым синтаксисом C++.

  • Вы можете столкнуться с проблемами вообще (не здесь), не помещая вычитание в скобку.

  • Было бы лучше, если бы вы могли создать две отдельные переменные для строки и текущего целого числа перед вызовом макроса CHECK_CONDITION, как показано ниже.

  • Вы передаете std::string, а не QString.

Но было бы еще приятнее, если бы вы могли просто описать вторую часть следующим образом:

QString myString = table.commonIn();
int curr = start - idx;

if(CHECK_CONDITION(myString, start, curr)) {
   findFalse = true;
}

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

Есть случаи, когда они имеют смысл, но есть альтернативы, такие как шаблон (который здесь не применим) или встроенные функции и методы (не уверен, применимо ли здесь). В зависимости от вашего варианта использования вы можете выбрать тот, который предпочитаете, но вы можете получить ответ, как заставить макрос работать в вашем случае.

Препроцессор не имеет понятия о типах, поэтому вы, когда вы объявляете #define с типами вам не нужно указывать тип параметра:

#define CHECK_CONDITION(condition, start, curr) { if(condition == "" ) return true; return (table.commonIn() == "team_id"? list()[start]->team() ==list()[curr]->team() :list()[start]->team() ==list()[curr]->team())}

Кроме того, #define раскрывается там, где вы его используете (препроцессор заменяет CHECK_CONDITION с этим блоком кода), поэтому ваш код не будет компилироваться по крайней мере по одной причине: вы будете вкладывать if внутри if условие, которое является синтаксической ошибкой.

Вместо этого используйте (возможно встроенную) функцию:

inline
bool check_condition(QString condition, int start, int curr) {
    if(condition == "" ) return true;
    return (
        table.commonIn() == "team_id"?
            list()[start]->team() == list()[curr]->team():
            list()[start]->team() == list()[curr]->team()
    )
}

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

Мои 2cents: вы должны увидеть препроцессор в C++ как последнее средство: у вас есть шаблоны, константные переменные и встроенные функции.

Основная причина, почему он был оставлен в C++ (вместо использования include одно ключевое слово или тому подобное), чтобы сохранить обратную совместимость с C. Никогда не используйте препроцессор, если любое другое решение не является слишком сложным.

#define в C/C++ это макроопределение, которое является простой текстовой заменой. Это определение больше похоже на функцию и пытается присвоить тип одному из параметров. Это не юридический синтаксис и, следовательно, QString часть должна быть удалена

В целом, хотя этот код не идеально подходит для макроса. Аргументы start а также curr оба используются несколько раз в расширении. Это означает, что если выражение макроса побочного действия передается макросу, оно может выполняться потенциально много раз. Функция была бы намного более подходящей здесь

Другие вопросы по тегам