2015-12-11 7 views
5

По существу то же, что и this question, но для C++.Могу ли я условно выбрать, какую переменную присваивать?

Самый простой способ сделать это было бы:

if (condition) { 
    a = f(x); 
} else { 
    b = f(x); 
} 

Хотя это отвечает моим потребностям, он всегда давало мне покоя, что я должен был повторить набрав п (х) в два раза, не говоря уже о расширении код из-за большого количества строк, когда будет выполняться только одна строка. Что делать, если у меня есть большой выбор переменных назначения на выбор?

switch(condition variable) { 
case 1: 
    var1 = f(x); 
    break; 
case 2: 
    var2 = f(x); 
    break; 
... 
case y: 
    vary = f(x); 
    break; 
} 

Это выглядит очень нелогично для меня.

Есть ли что-нибудь в C++, что по существу позволяет мне сделать следующее?

do-something-that-returns-a-lvalue = f(x); 

Простите меня, если это не называется lvalue, я все еще относительно новичок в C++. Но вы, ребята, понимаете, что я имею в виду - переменную назначения для присвоения значения.

+0

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

+0

Как это сделать? Каков тип возврата функции, которая должна выглядеть? – thegreatjedi

+0

Хотя это не прямой ответ на вопрос, 'fval = f (x); если (условие) a = fval; else b = fval' гораздо более разборчиво для меня, но все еще DRY. – Amadan

ответ

8

Вы можете сформировать ссылку или указатель на переменную, которую вы хотите назначить.

(condition ? a : b) = f(x); // reference 

выше версия была предложена aschepler в комментарии.

*(condition ? &a : &b) = f(x); // pointer 

Эталонная версия в основном эквивалентна следующему более подробному примеру с использованием вспомогательной функции.

template <typename T> 
T& 
conditional_reference(bool pred, T& yes, T& no) noexcept 
{ 
    return pred ? yes : no; 
} 

// And then later 

conditional_reference(condition, a, b) = f(x); 

Я считаю, что ваш традиционный if тогда else управление потоком, вероятно, еще лучший выбор с точки зрения кода ясности.

Если источник задания является более сложным выражением, чем просто f(x), вы можете сохранить его результат во временной переменной, а затем назначить эту переменную только в условном выражении. Семантика перемещения C++ 11 во многих случаях позволяет использовать такие временные файлы.

+3

Если 'a' и' b' имеют один и тот же тип, будет выполняться обычный старый '(условие? A: b) = f (x);'. – aschepler

+0

@aschepler Честно говоря, я был немного удивлен, что это работает, но, думая, через это, конечно, это так. Я это запомню. – 5gon12eder

+0

Это, скорее всего, точное решение, которое я ищу. Благодаря! Я приму это как ответ. – thegreatjedi

6

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

std::get<constexpr_indexer()>(std::tie(var1, var2, var3, var4)) = f(x); 

std::get, std::tie

+0

Спасибо за этот ответ! Я думаю, что это, в частности, очень полезно знать, хотя, к сожалению, он ограничен только временем компиляции. Жаль, что я не могу выбрать несколько ответов. – thegreatjedi

2

В инструкции коммутатора можно указать переменную-указатель (например, double * p).

switch(condition variable) { 
case 1: 
    p = & var1; 
    break; 
case 2: 
    p = & var2; 
    break; 
... 
case y: 
    p = & vary; 
    break; 
} 

Тогда вы можете сделать это после того, как вы скроете инструкцию.

*p = f(x); 
+0

Это не решит проблему. Теперь я должен сделать оператор switch с переменной указателя слева. Это по сути то же самое. Мой вопрос заключается в том, можно ли исключить оператор switch, и одна и та же функциональность объединяется в одну строку или что-то в этом роде. – thegreatjedi

+0

@thegreatjedi вы можете использовать тройной оператор, как предложено 5gon12eder. Но более того, что два условия и код станут нечитаемыми. –

0

Как и вопрос, с которым вы связались, у вас все еще есть XY problem. Зачем тебе это нужно? Почему вы чувствуете, что пишете больше кода, который потенциально нечитабелен и не поддается управлению, менее изящный, чем простое условие if/else? Но суть вопроса заключается в том, в каком правильном сценарии у вас было бы 26 (следуя вместе с алфавитом) переменных с одинаковым значением?

Если у вас есть сценарий, похожий на исходный вопрос (Дерево двоичного поиска), просто придерживайтесь одной переменной.

Пожалуйста, прочтите DRY unrelated, but nearly identical, code:

Вы не делаете DRY, потому что кто-то написал в книге где-то, что это хорошо делать, вы DRY, потому что на самом деле имеет ощутимые преимущества.

+0

@ Разведыватели Видя изменчивость ответов без четкой спецификации того, что фактически хочет ОП, кроме как «СУХОЙ», является сильным признаком «непонятного, что вы просите» или «слишком широкого». – user5666873

+0

Если вы считаете, что вопрос «слишком широк», или «непонятно, что вы спрашиваете», рекомендуемая процедура - попросить сузить или уточнить вопрос, и если это не сработает, отметьте его для закрытия. Это не повод для публикации широких или нечетких ответов. Тем не менее, я не чувствовал, что ваш ответ заслуживает голосования. – 5gon12eder

+1

Я столкнулся с экземплярами разных программ, где все, что я хочу сделать, это «выбрать, какую переменную присваивать». Я знаю, что существуют различные способы выбора ценности переменной, поэтому, естественно, мне просто интересно, если то же самое верно для наоборот, потому что я регулярно сталкивался с необходимостью для нее. Для меня что-то вроде оператора switch-case следует использовать, когда разные случаи имеют существенно отличающийся код, а не для повторения одного оператора n раз. Я не прошу решить одну проблему здесь и сейчас, но узнать, какие методы доступны мне. – thegreatjedi

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