Определить функцию с #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
оба используются несколько раз в расширении. Это означает, что если выражение макроса побочного действия передается макросу, оно может выполняться потенциально много раз. Функция была бы намного более подходящей здесь