2014-01-11 2 views
0

я хочу проверить, если н множественным время я использовать #define для этого объявления я хочу использовать его, но он не работаетОпределить функцию с #define в cpp?

#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; 
} 

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

+0

У аргументов макроса нет типов, оставьте 'QString'. –

+1

Почему бы не использовать функцию 'inline' вместо макроса? –

+0

@AlokSave: Возможно, OP хочет сгенерировать код, который легко интроспективен после этапа препроцессора и т. Д., Или просто хочет изучить макропрограммирование. – lpapp

ответ

1

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

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

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

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

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

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

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

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

, а затем вы можете сохранить остальную часть кода, как это:

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

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

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

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

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

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

Но было бы еще лучше, если вы могли бы просто вторая часть, как это:

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

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

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

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

1

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

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

2

Препроцессор не имеет понятия о типах, поэтому при объявлении #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() 
    ) 
} 

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

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

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

+0

+1, но рассмотрите использование неподписанного типа для 'start' и' curr', поскольку отрицательные значения не имеют смысла для этой функции. –

+0

@ DanielFrey На самом деле я не могу сказать, потому что я не знаю, как определяется «list». Он может принять соглашение Python о принятии отрицательных значений в качестве смещения от последнего (вместо первого) элемента. В этом случае 'int' будет иметь смысл ... –

+0

Встроенная функция не очень хороша для генерации кода, которая может быть проверена. – lpapp

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