У меня есть следующий оператор‹, который должен сортировать сначала по значению, а затем по другому значению:
inline bool operator < (const obj& a, const obj& b)
{
if(a.field1< b.field1)
return true;
else
return a.field2 < b.field2;
}
У меня такое ощущение, что это неверно и что вы не можете сделать это без еще одного третьего сравнительного теста для переменных-членов, но я не могу найти ни одного примера, где это не работает. Так что же это действительно так, как ожидалось? Благодарность
изменить: я бы закодировал его как:
inline bool operator < (const obj& a, const obj& b)
{
if(a.field1< b.field1)
return true;
else if(a.field1> b.field1)
return false;
else
return a.field2 < b.field2;
}
есть ли отличия? Я спрашиваю, потому что по опыту знаю, что мой правильный, но он длиннее первого.
if( obj(2,1) < obj(1,2) )
. - person Robᵩ   schedule 03.07.2012<
, затем на>
, продолжая только последующие проверки в случае==
. Затем для последнего поля вас не волнует==
против>
, поэтому просто верните результат<
. Лично я бы написал каждый оператор if в одной строке и не беспокоился бы оelse
, посколькуreturn
все равно выходит из функции. - person Steve314   schedule 03.07.2012(a.f1 < b.f1)
, а затем(b.f1 < a.f1)
. IIRC вы получаете автоматическийoperator>
, когда вы определяетеoperator<
из стандартной библиотеки, но это нормально, даже если по какой-то причине это не удается. - person Steve314   schedule 03.07.2012return a.field1 != b.field1 ? a.field1 < b.field1 : a.field2 < b.field2;
(но с разрывами строк, которые я не могу добавить в комментарий). - person James Kanze   schedule 03.07.2012!=
, а затем<
может показаться более симметричным и может обеспечить более равномерную производительность (за счет замедления случая<
до соответствия>
), но ни один из этих вопросов не является для меня убедительным. - person Steve314   schedule 03.07.2012if
s, поэтому нет никакой разницы в удобочитаемости. Разница в том, что при использовании тернарного оператораreturn
s не находятся вif
s, и, поскольку есть только одна ветвь, сразу становится ясно, что нет такой ветви, где возврат был бы забыт. - person James Kanze   schedule 03.07.2012if
/else
является возврат. (Но вам все равно нужно убедиться, что каждыйif
имеетelse
.) Что касается цепочки тернарных операторов, то это должно быть стандартной идиомой C++, которую сразу узнает любой компетентный практик. Но это не так; на самом деле, я не знаю ни одного учебника, в котором это представлено. (Джон Поттер впервые показал мне его, а я в то время использовал C++ более 10 лет.) Правильно отформатированные цепные тернарные операторы (чего я не могу сделать в комментарии) очень удобочитаемы. - person James Kanze   schedule 04.07.2012if
естьelse
по очень простой причине - в моей идиоме вообще не используетсяelse
. Помните - я предпочитаю не зависеть от!=
. Для этого у меня нет вложенных операторовif
, только цепочка из них. - person Steve314   schedule 04.07.2012if
, я как читатель имею право предположить, что это будет выполнено. - person James Kanze   schedule 04.07.2012return
- есть ещеbreak
,continue
,throw
- даже редкий частный случай, когдаgoto
оправдано. Конечно, если бы операторif
был нетривиальным, тоreturn
стал бы скрытым выходом, и я бы с вами согласился. Но когда все тело в однострочном выраженииif
представляет собой либоreturn true;
, либоreturn false;
, нет оправдания тому, что вы этого не видите. - person Steve314   schedule 04.07.2012