Могу ли я использовать более одной инструкции во втором или третьем операнде тернарного оператора?

Могу я сделать что-то очень похожее, вот так?

question ? func1(), val=5 : func2()

Я бы хотел поставить более одной инструкции на место первого или второго параметра. Это разрешимо?


person Erdős András    schedule 22.07.2015    source источник
comment
Да, используйте круглые скобки и оператор запятой.   -  person The Paramagnetic Croissant    schedule 22.07.2015
comment
Практическое правило: не используйте ?: для потока управления.   -  person Oliver Charlesworth    schedule 22.07.2015
comment
Или избегайте этого, чтобы сделать его читабельным (даже если вы сомневаетесь в использовании оператора запятой)   -  person    schedule 22.07.2015
comment
Просто замените его на _1 _-_ 2_. Проблема решена, и удобочитаемость улучшена.   -  person Christian Hackl    schedule 22.07.2015


Ответы (4)


Да, взгляните на следующий пример:

#include <iostream>

int main()
{
    int x,y,z;
    double d = 2.5;


    auto f = (d == 2.2) ? (x=5,y=10,z=0,2000) : (x=15,y=0,z=20,1000);

    std::cout << x << " " << y << " " << z << " " << f << std::endl;


    std::cin.get();
    return 0;
}

Не так чисто, поэтому предлагаю сделать его более читаемым.

person Community    schedule 22.07.2015
comment
Обратите внимание, как указано в комментарии к исходному вопросу, что круглые скобки важны, особенно вокруг третьего аргумента тернарного оператора. Без них все, что находится после первой запятой, интерпретируется как следующее за тройкой, а не как ее часть. См. stackoverflow.com/questions/9189522/ - person Mathew; 22.07.2015

Если под «инструкцией» (что даже не имеет значения, когда речь идет о формулировке C ++) вы имеете в виду «выражение», то обязательно: скобки и оператор запятой придут на помощь!

SSCCE:

#include <cstdio>

int main()
{
    int x = (1, 0) ? 2, 3 : (4, 5);
    printf("%d\n", x); // prints 5
}
person The Paramagnetic Croissant    schedule 22.07.2015
comment
Это странный пример, потому что у вас нет побочных эффектов в ваших операндах-запятых. Ваш код эквивалентен int x = 0 ? 3 : 5;. А почему printf в вопросе C ++? - person Christian Hackl; 22.07.2015
comment
@ChristianHackl, что плохого в отсутствии побочных эффектов? Это все еще выражение (так что оно демонстрирует ответ на вопрос OP), не так ли? Что касается printf, это намного лучше, чем пытаться сдвинуть поток влево. - person The Paramagnetic Croissant; 22.07.2015
comment
Побочные эффекты - единственная причина для использования оператора запятой в первую очередь. - person Christian Hackl; 22.07.2015
comment
@ChristianHackl, если вы последуете приведенному выше хорошему совету (о том, чтобы избегать совершенно и излишне умного кода), то побочные эффекты - еще одна причина не использовать оператор запятой. В любом случае, независимо от того, являются ли они причиной - мой пример все еще отвечает на то, о чем спрашивал OP. - person The Paramagnetic Croissant; 22.07.2015
comment
Я не понимаю. Вы намеренно разместили пример, в котором оператор запятой не имеет смысла, просто чтобы подчеркнуть тот факт, что его не следует использовать для потока управления? - person Christian Hackl; 22.07.2015
comment
@ChristianHackl нет, я опубликовал один без побочных эффектов, чтобы сделать пример максимально простым. - person The Paramagnetic Croissant; 22.07.2015

Обсуждение тернарного оператора можно найти на странице http://www.cplusplus.com/forum/articles/14631/, в котором говорится об этом. В комментариях к обсуждению есть несколько примеров, показывающих использование вызовов функций и множественных операций в тернарном операторе. Хотя, для ясности, может быть лучше не делать слишком много вещей одновременно в тернарном операторе - это может стать трудным для чтения довольно быстро.

person Tyler    schedule 22.07.2015

Спасибо за эти быстрые и полезные ответы!

Итак, я программирую Arduino на C ++, и это полный пример кода:

void setup() {
  Serial.begin(115200);
  bool b = false;
  int val = 0;

  b ? func1() : (func2(), val = 2);

  Serial.println(val);
}

void loop() {}

void func1 (){
     Serial.println("func1");
}

void func2 (){
    Serial.println("func2");  
}

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

sketch_jul22a.ino: In function 'void setup()':
sketch_jul22a:8: error: second operand to the conditional operator is of type 'void', but the third operand is neither a throw-expression nor of type 'void'
second operand to the conditional operator is of type 'void', but the third operand is neither a throw-expression nor of type 'void'

Я использовал функции типа int вместо типа void, и проблема решена:

int func1 (){
     Serial.println("func1");
     return 0;
}

int func2 (){
    Serial.println("func2");
    return 0;
}
person Erdős András    schedule 22.07.2015