2016-07-25 2 views
1

У меня есть следующий код:Определение сопза «переменные» внутри, если блок

Foo a; 
if (some_fairly_long_condition) { 
    a = complicated_expression_to_make_foo_1(); 
} else { 
    a = complicated_expression_to_make_foo_2(); 
} 

У меня есть две проблем с этим:

  1. a является const и должен быть объявлен так
  2. в «пустой» конструктор, Foo() вызван без причины (возможно, это оптимизировано?)

Один из способов исправить это с помощью тройной оператор:

const Foo a = some_fairly_long_condition? 
     complicated_expression_to_make_foo_1(): 
     complicated_expression_to_make_foo_2(); 

Является ли это хорошая практика? Как вы это делаете?

+4

Это вопрос мнения, и, на мой взгляд, да, это хороший пример использования условного оператора. – juanchopanza

+3

Другим вариантом будет 'const Foo a = compute_foo();' и положить сложный материал в отдельную функцию. Сделал бы его повторно используемым. –

+0

Некоторое обсуждение на эту тему раньше: http://stackoverflow.com/q/4192225/168175, с другой стороны – Flexo

ответ

2

Чтобы ответить на второй части Вашего вопроса:
Я обычно ставлю код инициализации в лямбда:

const Foo a = [&]()->Foo{ 
    if (some_fairly_long_condition) { 
     return complicated_expression_to_make_foo_1(); 
    } else { 
     return complicated_expression_to_make_foo_2(); 
    } 
}(); 

В большинстве случаев вы должны даже быть в состоянии опустить тип возвращаемого трейлинга, так вы можете написать

const Foo a = [&](){ ... 

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

+3

Конечно, но вопрос в том, является ли условный оператор хорошим способом обойти это. И я думаю, что это лучше, чем эта лямбда. – juanchopanza

+0

@juanchopanza: Насколько мне известно, это зависит от того, являются ли 'сложное_выражение'' и' some_fairly_long_condition' просто заполнителями имен функций или фактически сложными и длинными выражениями. Конечно, вы можете добиться многого путем «правильного» * ​​форматирования, но это часто не выполняется при автоматическом форматировании, и, кроме того, лямбда-версия позволяет разбить эти утверждения на более простые части. – MikeMB

+1

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

0

Если проблема избежать оператора ternaty и ваша цель состоит в том, чтобы определить константу а, этот код вариант:

Foo aux; 
if (some_fairly_long_condition) { 
    aux = complicated_expression_to_make_foo_1(); 
} else { 
    aux = complicated_expression_to_make_foo_2(); 
} 
const Foo a(aux); 

Это хорошее решение, без какой-либо новой функции --- а лямбды --- и включая код в строке, как вы хотите.