Здравствуйте, Какая разница, Вы писали:
КР>Здравствуйте, Pavel515, Вы писали:
P>>Привет Всем!
P>>"Я еще не волшебник, а только учусь!"
P>>наверное что-то не понимаю!
P>>вот такой код:
P>>typedef pair<int,int> range_t; P>>bool operator<(const range_t& A,const range_t& B){return (A.first<B.first)&&(A.second<B.second)&&(A.second<B.first);}; P>>typedef set<range_t> ranges_t;
P>>мой оператор "<" остается за бортом! ваполняется стандартный из <utility>
Здравствуйте, LuckLess, Вы писали:
P>>typedef pair<int,int> range_t; P>>bool operator<(const range_t& A,const range_t& B){return (A.first<B.first)&&(A.second<B.second)&&(A.second<B.first);};
P>>typedef set<range_t> ranges_t;
LL>Для того, чтобы std::set воспользовался твоим оператором < тебе надо перегрузить std::less<range_t>, так — чтобы тот звал твой оператор.
Этого нельзя делать, потому что стандартные шаблоны можно специализировать только для пользовательских типов, а range_t таковым не является — он всего лишь псевдоним для стандартного же std::pair<int, int>.
Этот operator< не удовлетворяет требованиям, накладываемым на предикат сравнения (не является моделью концепции StrictWeakOrdering). В частности, он объявляет эквивалентными все пересекающиеся интервалы. Но из того, что интервалы A, B пересекаются, и B, C пересекаются, вовсе не следует, что A, C будут пересекаться (отношение нетранзитивно). Контрпример: range_t A(0, 2), B(1, 4), C(3, 5). Следовательно, этот предикат нельзя использовать с std::set.
Однако, компилятор игнорирует его не поэтому, а потому, что range_t — это псевдоним стандартного типа std::pair<int, int>, который находится в namespace std, и поэтому operator< тоже берётся из namespace std. Засунуть же свою реализацию чего бы то ни было в namespace std можно только тогда, когда она зависит от какого-либо пользовательского типа.
P>typedef set<range_t> ranges_t;
Здравствуйте, Centaur, Вы писали:
C>Здравствуйте, Pavel515, Вы писали:
P>>typedef pair<int,int> range_t; P>>bool operator<(const range_t& A,const range_t& B){return (A.first<B.first)&&(A.second<B.second)&&(A.second<B.first);};
C>Этот operator< не удовлетворяет требованиям, накладываемым на предикат сравнения (не является моделью концепции StrictWeakOrdering). В частности, он объявляет эквивалентными все пересекающиеся интервалы. Но из того, что интервалы A, B пересекаются, и B, C пересекаются, вовсе не следует, что A, C будут пересекаться (отношение нетранзитивно). Контрпример: range_t A(0, 2), B(1, 4), C(3, 5). Следовательно, этот предикат нельзя использовать с std::set.
оно еще и не антисимметрично (A(0,2) B(1,4))
порядок(x,y) = !порядок(y,x)
посто на этапе заполнения все пересекающиеся интервалы уйдут и во множестве остануться только непересекающиеся
задача: в последовательности непересекающихся интервалов (1-2 и 2-3 — пересекаются, а 1-2 и 3-4 — нет), определить: входит ли конкретное одно число а в какой-нибудь интервал множества или нет?
C>Однако, компилятор игнорирует его не поэтому, а потому, что range_t — это псевдоним стандартного типа std::pair<int, int>, который находится в namespace std, и поэтому operator< тоже берётся из namespace std. Засунуть же свою реализацию чего бы то ни было в namespace std можно только тогда, когда она зависит от какого-либо пользовательского типа.
P>>typedef set<range_t> ranges_t;
Если хочешь выиграть в лотерею, то купи, хотя-бы лотерейный билет. (В.Мэгре)