Здравствуйте, igna, Вы писали:
I>size_t не обязан быть самым большим из целочисленных типов, то есть результат вычисления last — first может не поместиться в size_t.
Расскажи какому математику, что у программистов проблема со сравнением чисел из одного подмножеста Z с абсолютно однозначно определенным порядком, что они в спецификации лазят и спорят — тот и помереть со смеху может
Здравствуйте, igna, Вы писали:
I>Здравствуйте, php-coder, Вы писали:
I>
PC>> if (source.size() > static_cast<size_t>(last - first))
I>
I>size_t не обязан быть самым большим из целочисленных типов, то есть результат вычисления last — first может не поместиться в size_t.
Насколько я понимаю, неявное привидение типа здесь все равно будет. Поэтому, собственно говоря, и выдается варнинг...
Вопрос к более сведующим, в сравнении (last — first) будет всегда приводиться к size_t?
Здравствуйте, Кодёнок, Вы писали:
Кё>Расскажи какому математику, что у программистов проблема со сравнением чисел из одного подмножеста Z с абсолютно однозначно определенным порядком, что они в спецификации лазят и спорят — тот и помереть со смеху может
Вот еще пример для математиков:
#include <iostream>
using namespace std;
int main()
{
unsigned int one = 1;
if (one < -1)
cout << "1 < -1\n";
}
Логика создателей C разрешивших неявное преобразование int в unsigned int мне непонятна. Эффективность и в случае необходимости явного преобразования типа никуда бы не делась.
Здравствуйте, igna, Вы писали:
I>template <class CONT, class FI> I>bool my_copy(CONT const& source, FI first, FI last) I>{ I> if (source.size() > last — first) // VC++ 9.0 — warning C4018: '>' : signed/unsigned mismatch I> return false; I> copy(source.begin(), source.end(), first); I> return true; I>}
[/ccode]
на сколько я понимаю, по логике программы всё корректно, напрягает только варнинг, возникший из-за оператора вычитания. А если его заменить на сложение?
if (source.size() + first > last) // так нормально?return false;
Здравствуйте, Bell, Вы писали:
B>size_type can represent any non-negative value of difference_type
...Из чего не следует, что он может представлять что-то сверх того.
Этим лагом в стандарте пользуются разработчики компиляторов, делая size_t беззнаковым той же разрядности, что и ptrdiff_t.
В общем, удобно. Не считая проблем со смешанной арифметикой.
Вот если бы наоборот, утверждалось бы, что difference_type мог представлять любое реалистичное значение size_type, то можно было бы спокойно кастить size() к difference_type и не париться.
По смыслу — так оно и есть.
Если компилятор честный и допускает существование контейнеров размером более чем в половину сегмента данных, то ptrdiff_t должен быть длиннее, чем адресные регистры — чтоб хранить знак разности.
Но тогда, для удобства, нужно поднять и разрядность size_t.
И получить мучительную арифметику, не влезающую в регистры процессора.
Какой бы каст ни был — явный, неявный, — здесь чисто математически нужны внешние гарантии, что last<=first. (именно так! нужно быть внимательным к тому, что пишешь). В противном случае отрицательное значение превратится в мега-положительное.
Здравствуйте, Кодёнок, Вы писали:
Кё>Расскажи какому математику, что у программистов проблема со сравнением чисел из одного подмножеста Z с абсолютно однозначно определенным порядком, что они в спецификации лазят и спорят — тот и помереть со смеху может
Расскажи этому математику, что это только кажется, что подмножество одно и то же, а на самом деле там два кольца вычетов, по-разному отображаемые на Z и обратно.
Он не со смеху помрёт, а с печали за наши судьбы.
W>>if (source.size() + first > last) // так нормально?
I>
I>Интересно, но не работает, если sizeof(source.size()) > sizeof(first). Ситуация не самая вероятная, но все же возможная.
Не работает по другой причине: first+source.size() может вылететь за пределы области определения этих итераторов. В этом случае поведение не определено, или, в лучшем случае, не специфицировано.
В исходном примере копировали вектор со списком. Сделайте advance(first,source.size()) за конец списка, узнаете всякое нехорошее.
К>Что это за контейнер, в котором неотрицательная* дельта вылезает из размера? К>Противоречие здравому смыслу, однако.
Впрочем, если последовательность (first,last) отображает что-то за пределами адресного пространства (мега-файл; функцию над длинными целыми; ещё что-то тому подобное), то конечно.
А нужно ли иметь такую функцию, которая в случае перебора длины просто выходит с false?
Может быть, лучше копировать сколько возможно, и возвращать остаток обоих последовательностей?
template<class I, class O>
pair<I,O> copy_zipped(I ib, I ie, O ob, O oe)
{
for( ; ib!=ie && ob!=oe; ++ib, ++ob )
*ob = *ib;
return make_pair(ib,ob);
}
// заполнение контейнера из множества источников
destination::iterator top = dst.begin(), enough = dst.end();
if(top != enough)
top = copy_zipped(src1.begin(), src1.end(), top, enough).second;
if(top != enough)
top = copy_zipped(src2.begin(), src2.end(), top, enough).second;
.....
// распихивание контейнера во множество приёмников
source::iterator start = src.begin(), finish = dst.end();
if(start != finish)
start = copy_zipped(start, finish, dst1.begin(), dst1.end()).first;
if(start != finish)
start = copy_zipped(start, finish, dst2.begin(), dst2.end()).first;
.....
Здравствуйте, Кодт, Вы писали:
Кё>>Расскажи какому математику, что у программистов проблема со сравнением чисел из одного подмножеста Z с абсолютно однозначно определенным порядком, что они в спецификации лазят и спорят — тот и помереть со смеху может
К>Расскажи этому математику, что это только кажется, что подмножество одно и то же, а на самом деле там два кольца вычетов, по-разному отображаемые на Z и обратно.
Какие еще кольца вычетов?!
Есть какие-то теоретические трудности со сравнением двух чисел из произвольных интервалов A..B и C..D? Или то, что они закодированы в виде 0..(B-A) и 0..(D-C) принципиально усложняет задачу?
Здравствуйте, Кодёнок, Вы писали:
Кё>Какие еще кольца вычетов?!
Беззнаковые целые реализуют арифметику по модулю 2^разрядность.
Кё>Есть какие-то теоретические трудности со сравнением двух чисел из произвольных интервалов A..B и C..D? Или то, что они закодированы в виде 0..(B-A) и 0..(D-C) принципиально усложняет задачу?
Трудности в том, что в С++ нет "произвольных интервалов". Есть независимые множества аппаратно реализованных типов, между которыми установлены отображения. Это постоянно ускользает из внимания, за кажущейся похожестью этих типов на подмножества Z и R.
Задачу усложняет то, что операция сравнения работает быстро, только если числа относятся к одному и тому же множеству. Не к абстрактному Z или R, а к аппаратно реализованному.
А когда множества разные, то есть 3 пути
— или дорогое сравнение гетерогенных объектов (мысленно отображая их на Z или R)
— или дешёвое приведение к какому-то аппаратно реализованному типу и затем дешёвое сравнение
— или послать всех нафиг
Как в спецификации сказано, так и будет сделано.
В Хаскелле ты не сможешь сравнить Int (аппаратный) и Integer (неограниченная разрядность) без предварительного отображения одного на другое. То есть, это 3-й вариант.
В Питоне — им терять нечего — язык интерпретируемый, расширяют до длинного целого и сравнивают.
В С++ — ради скорости говорят, что программист ССЗБ. Если дефолтное приведение типов устраивает, то нет переплаты. Если не устраивает — то нужно явно переплатить именно в этом месте.
Здравствуйте, Кодт, Вы писали:
К>В С++ — ради скорости говорят, что программист ССЗБ.
Никакой скорости не повредило бы, если бы при сравнении (сложении, вычитании ...) int и unsigned int требовалось явное приведение типа. Даже скорости написания программы с учетом отладки пошло бы на пользу.